From b300c0a12ff93a2192c0c310d41df70d5348b010 Mon Sep 17 00:00:00 2001 From: rnarubin Date: Fri, 1 Dec 2023 09:15:16 -0800 Subject: [PATCH] Separate services from connectors (#36) * Separate services from connectors Previously the library attempted to abstract over different HTTP(s) connectors by passing them as generics through various types. Although this allows certain flexibility (e.g. choosing openssl vs rustls), it was probably the wrong abstraction layer in the first place. This change moves most of the genericism to the grpc-service layer for grpc services (bigtable and pubsub). The library's "common" path via builders will provide a sensible default implementation, but it will now be possible to substitute the entire tower::service stack provided to the grpc API. This is more flexible than the prior connector abstraction, but also harder to use (you basically have to build everything yourself). This feels like the right balance between a batteries-included default and a build-your-own option. Along the way I've also made some updates to non-exhaustivity in generated code, to help ease future changes without breaking semver. This is unfortunately less ergonomic, but not _too_ bad. Future changes may include some builder pattern to make protobuf construction easier. The GCS API is still largely the same, however it is still not in an ideal place. Future changes may bring it more towards service abstraction. Finally, this change includes updates to tonic and prost, bringing them up to the latest versions. Supersedes #30 Fixes #35 --- Cargo.lock | 377 +++++------------- Cargo.toml | 32 +- examples/bigtable.rs | 10 + examples/pubsub_stream.rs | 62 ++- generators/Cargo.toml | 4 +- generators/src/grpc.rs | 23 +- src/auth/grpc.rs | 27 +- src/auth/mod.rs | 4 + src/bigtable/admin.rs | 126 +++--- src/bigtable/client_builder.rs | 39 +- src/bigtable/mod.rs | 78 +++- src/builder.rs | 215 +++-------- src/generated/google.api.rs | 76 +++- src/generated/google.bigtable.admin.v2.rs | 450 ++++++++++++++++------ src/generated/google.bigtable.v2.rs | 151 +++++++- src/generated/google.iam.v1.rs | 21 +- src/generated/google.longrunning.rs | 21 +- src/generated/google.pubsub.v1.rs | 288 ++++++++++++-- src/generated/google.r#type.rs | 32 ++ src/generated/google.rpc.rs | 7 +- src/grpc/mod.rs | 9 + src/lib.rs | 10 +- src/pubsub/client_builder.rs | 44 +-- src/pubsub/emulator.rs | 1 + src/pubsub/mod.rs | 129 +++---- src/pubsub/publish_sink.rs | 82 ++-- src/pubsub/streaming_subscription.rs | 61 ++- src/storage.rs | 28 +- tests/bigtable_client.rs | 13 +- tests/pubsub_client.rs | 275 ++++++------- 30 files changed, 1555 insertions(+), 1140 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d133b94..2c38500 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -182,9 +182,12 @@ checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] name = "cc" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -273,15 +276,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "ct-logs" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1a816186fa68d9e426e3cb4ae4dff1fcd8e4a2c34b781bf7a822574a0d0aac8" -dependencies = [ - "sct 0.6.1", -] - [[package]] name = "cxx" version = "1.0.94" @@ -367,21 +361,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.1.0" @@ -488,9 +467,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if", "libc", @@ -623,54 +602,20 @@ dependencies = [ "want", ] -[[package]] -name = "hyper-openssl" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6ee5d7a8f718585d1c3c61dfde28ef5b0bb14734b4db13f5ada856cdc6c612b" -dependencies = [ - "http", - "hyper", - "linked_hash_set", - "once_cell", - "openssl", - "openssl-sys", - "parking_lot", - "tokio", - "tokio-openssl", - "tower-layer", -] - [[package]] name = "hyper-rustls" -version = "0.22.1" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ - "ct-logs", "futures-util", - "hyper", - "log", - "rustls 0.19.1", - "rustls-native-certs 0.5.0", - "tokio", - "tokio-rustls 0.22.0", - "webpki", -] - -[[package]] -name = "hyper-rustls" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0646026eb1b3eea4cd9ba47912ea5ce9cc07713d105b1a14698f4e6433d348b7" -dependencies = [ "http", "hyper", "log", - "rustls 0.21.0", - "rustls-native-certs 0.6.2", + "rustls", + "rustls-native-certs", "tokio", - "tokio-rustls 0.24.0", + "tokio-rustls", ] [[package]] @@ -761,9 +706,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.141" +version = "0.2.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "link-cplusplus" @@ -774,31 +719,6 @@ dependencies = [ "cc", ] -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - -[[package]] -name = "linked_hash_set" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47186c6da4d81ca383c7c47c1bfc80f4b95f4720514d860a5407aaf4233f9588" -dependencies = [ - "linked-hash-map", -] - -[[package]] -name = "lock_api" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" -dependencies = [ - "autocfg", - "scopeguard", -] - [[package]] name = "log" version = "0.4.17" @@ -901,79 +821,18 @@ version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" -[[package]] -name = "openssl" -version = "0.10.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e30d8bc91859781f0a943411186324d580f2bbeb71b452fe91ae344806af3f1" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.15", -] - [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" -[[package]] -name = "openssl-sys" -version = "0.9.85" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d3d193fb1488ad46ffe3aaabc912cc931d02ee8518fe2959aea8ef52718b0c0" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "overload" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" -[[package]] -name = "parking_lot" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-sys 0.45.0", -] - [[package]] name = "paste" version = "1.0.12" @@ -1018,12 +877,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkg-config" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" - [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1065,9 +918,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.11.9" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" dependencies = [ "bytes", "prost-derive", @@ -1075,22 +928,22 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.11.9" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" dependencies = [ "anyhow", "itertools", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.15", ] [[package]] name = "prost-types" -version = "0.11.9" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" dependencies = [ "prost", ] @@ -1193,15 +1046,6 @@ dependencies = [ "rand_core 0.3.1", ] -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags", -] - [[package]] name = "regex" version = "1.7.3" @@ -1246,63 +1090,52 @@ dependencies = [ "cc", "libc", "once_cell", - "spin", - "untrusted", + "spin 0.5.2", + "untrusted 0.7.1", "web-sys", "winapi", ] [[package]] -name = "rustc_version" -version = "0.4.0" +name = "ring" +version = "0.17.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "684d5e6e18f669ccebf64a92236bb7db9a34f07be010e3627368182027180866" dependencies = [ - "semver", + "cc", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.48.0", ] [[package]] -name = "rustls" -version = "0.19.1" +name = "rustc_version" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "base64 0.13.1", - "log", - "ring", - "sct 0.6.1", - "webpki", + "semver", ] [[package]] name = "rustls" -version = "0.21.0" +version = "0.21.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07180898a28ed6a7f7ba2311594308f595e3dd2e3c3812fa0a80a47b45f17e5d" +checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9" dependencies = [ "log", - "ring", + "ring 0.17.6", "rustls-webpki", - "sct 0.7.0", -] - -[[package]] -name = "rustls-native-certs" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a07b7c1885bd8ed3831c289b7870b13ef46fe0e856d288c30d9cc17d75a2092" -dependencies = [ - "openssl-probe", - "rustls 0.19.1", - "schannel", - "security-framework", + "sct", ] [[package]] name = "rustls-native-certs" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", "rustls-pemfile", @@ -1321,12 +1154,12 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.100.1" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring", - "untrusted", + "ring 0.17.6", + "untrusted 0.9.0", ] [[package]] @@ -1350,36 +1183,20 @@ dependencies = [ "windows-sys 0.42.0", ] -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - [[package]] name = "scratch" version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1792db035ce95be60c3f8853017b3999209281c24e2ba5bc8e59bf97a0c590c1" -[[package]] -name = "sct" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "sct" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" dependencies = [ - "ring", - "untrusted", + "ring 0.16.20", + "untrusted 0.7.1", ] [[package]] @@ -1509,6 +1326,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "strsim" version = "0.8.0" @@ -1736,36 +1559,13 @@ dependencies = [ "syn 2.0.15", ] -[[package]] -name = "tokio-openssl" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08f9ffb7809f1b20c1b398d92acf4cc719874b3b2b2d9ea2f09b4a80350878a" -dependencies = [ - "futures-util", - "openssl", - "openssl-sys", - "tokio", -] - -[[package]] -name = "tokio-rustls" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" -dependencies = [ - "rustls 0.19.1", - "tokio", - "webpki", -] - [[package]] name = "tokio-rustls" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0d409377ff5b1e3ca6437aa86c1eb7d40c134bfec254e44c830defa92669db5" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.0", + "rustls", "tokio", ] @@ -1796,16 +1596,15 @@ dependencies = [ [[package]] name = "tonic" -version = "0.9.2" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" +checksum = "d560933a0de61cf715926b9cac824d4c883c2c43142f787595e48280c40a1d0e" dependencies = [ + "async-stream", "async-trait", "axum", "base64 0.21.0", "bytes", - "futures-core", - "futures-util", "h2", "http", "http-body", @@ -1814,12 +1613,17 @@ dependencies = [ "percent-encoding", "pin-project", "prost", + "rustls", + "rustls-native-certs", + "rustls-pemfile", "tokio", + "tokio-rustls", "tokio-stream", "tower", "tower-layer", "tower-service", "tracing", + "webpki-roots", ] [[package]] @@ -1975,6 +1779,12 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.3.1" @@ -1988,9 +1798,9 @@ dependencies = [ [[package]] name = "uuid" -version = "0.8.2" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" dependencies = [ "getrandom", ] @@ -2001,12 +1811,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "vec_map" version = "0.8.2" @@ -2106,14 +1910,10 @@ dependencies = [ ] [[package]] -name = "webpki" -version = "0.21.4" +name = "webpki-roots" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" -dependencies = [ - "ring", - "untrusted", -] +checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" [[package]] name = "winapi" @@ -2179,6 +1979,15 @@ dependencies = [ "windows-targets 0.42.2", ] +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -2295,7 +2104,7 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "ya-gcp" -version = "0.10.0" +version = "0.11.0" dependencies = [ "approx", "async-channel", @@ -2306,8 +2115,7 @@ dependencies = [ "http", "humantime-serde", "hyper", - "hyper-openssl", - "hyper-rustls 0.22.1", + "hyper-rustls", "paste", "pin-project", "prost", @@ -2315,6 +2123,8 @@ dependencies = [ "quickcheck", "quickcheck_macros", "rand 0.8.5", + "rustls", + "rustls-native-certs", "serde", "serde_json", "structopt", @@ -2328,14 +2138,15 @@ dependencies = [ "tracing-subscriber", "tracing-tree", "uuid", + "webpki-roots", "yup-oauth2", ] [[package]] name = "yup-oauth2" -version = "8.2.0" +version = "8.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6135ad28f1957d676384074df0ad1dd920966834bddd973da86119378b4964d7" +checksum = "364ca376b5c04d9b2be9693054e3e0d2d146b363819d0f9a10c6ee66e4c8406b" dependencies = [ "anyhow", "async-trait", @@ -2343,11 +2154,11 @@ dependencies = [ "futures", "http", "hyper", - "hyper-rustls 0.24.0", + "hyper-rustls", "itertools", "log", "percent-encoding", - "rustls 0.21.0", + "rustls", "rustls-pemfile", "seahash", "serde", diff --git a/Cargo.toml b/Cargo.toml index 894ed3d..8e30f0c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ya-gcp" -version = "0.10.0" +version = "0.11.0" authors = ["Renar Narubin "] edition = "2021" description = "APIs for using Google Cloud Platform services" @@ -30,10 +30,10 @@ path = "examples/bigtable.rs" required-features = ["bigtable"] [features] -default = ["rustls"] +default = ["rustls-native-certs"] -rustls = ["hyper-rustls"] -openssl = ["hyper-openssl"] # TODO maybe should be native-tls instead? +rustls-native-certs = ["dep:rustls-native-certs", "tonic?/tls-roots"] +webpki-roots = ["dep:webpki-roots", "tonic?/tls-webpki-roots"] # an internal feature used by services running grpc grpc = ["tonic", "prost", "prost-types", "tower", "derive_more"] @@ -51,27 +51,29 @@ futures = "0.3" http = "0.2" humantime-serde = "1" hyper = "0.14" +hyper-rustls = "0.24.2" paste = "1" rand = "0.8" +rustls = "0.21.8" serde = { version = "1", features = ["derive"] } thiserror = "1" tokio = { version = "1", features = ["time"] } -tracing = "0.1" -yup-oauth2 = "8.1" +tracing = "0.1.37" +yup-oauth2 = "8.3.0" async-stream = { version = "0.3", optional = true } async-channel = { version = "1", optional = true } derive_more = { version = "0.99", optional = true } -hyper-openssl = { version = "0.9", optional = true } -hyper-rustls = { version = "0.22", features = ["rustls-native-certs"], optional = true } pin-project = { version = "1.0.11", optional = true } -prost = { version = "0.11", optional = true } -prost-types = { version = "0.11", optional = true } +prost = { version = "0.12.3", optional = true } +prost-types = { version = "0.12.3", optional = true } +rustls-native-certs = { version = "0.6.3", optional = true } tame-gcs = { version = "0.10.0", optional = true } tempdir = { version = "0.3", optional = true } -tonic = { version = "0.9", optional = true } +tonic = { version = "0.10.2", optional = true } tower = { version = "0.4", features = ["make"], optional = true } -uuid = { version = "0.8.1", features = ["v4"], optional = true } +uuid = { version = "1.6", features = ["v4"], optional = true } +webpki-roots = { version = "0.25.3", optional = true } [dev-dependencies] approx = "0.5" @@ -84,12 +86,6 @@ tokio = { version = "1.4.0", features = ["rt-multi-thread", "time", "test-util"] tracing-subscriber = { version = "0.3", features = ["env-filter"] } tracing-tree = "0.2" -[package.metadata.cargo-udeps.ignore] -# hyper-openssl is only used (and thus detected) if the feature "openssl" is -# enabled _and_ "rustls" is disabled. CI builds with --all-features, so udeps -# fails unless we ignore the package explicitly -normal = ["hyper-openssl"] - [package.metadata.docs.rs] rustdoc-args = ["--cfg", "docsrs"] all-features = true diff --git a/examples/bigtable.rs b/examples/bigtable.rs index 6f2ae8a..06f3f5a 100644 --- a/examples/bigtable.rs +++ b/examples/bigtable.rs @@ -32,6 +32,8 @@ async fn main() -> Result<(), Box> { AuthFlow::NoAuth }; + println!("Creating clients"); + let config = ClientBuilderConfig::new().auth_flow(auth); let builder = ClientBuilder::new(config).await?; @@ -51,6 +53,8 @@ async fn main() -> Result<(), Box> { ) .await?; + println!("Creating table `{}`", &args.table_name); + match admin .create_table( &args.table_name, @@ -69,13 +73,18 @@ async fn main() -> Result<(), Box> { } } + println!("Reading tables"); + let tables: Vec<_> = admin.list_tables().await?.collect().await; + println!("got tables {:?}", tables); let mut client = builder .build_bigtable_client(bigtable_config, &args.project_name, &args.instance_name) .await?; + println!("setting data"); + client .set_row_data( &args.table_name, @@ -84,6 +93,7 @@ async fn main() -> Result<(), Box> { [("col1", "value"), ("col2", "value")], ) .await?; + println!("set data done"); println!( "all data: {:?}", diff --git a/examples/pubsub_stream.rs b/examples/pubsub_stream.rs index a95fcae..751415b 100644 --- a/examples/pubsub_stream.rs +++ b/examples/pubsub_stream.rs @@ -58,31 +58,38 @@ async fn main() -> Result<(), Box> { println!("Creating topic {}", &topic_name); publisher - .create_topic(pubsub::api::Topic { - name: topic_name.clone().into(), - ..pubsub::api::Topic::default() + .raw_api_mut() + .create_topic({ + let mut t = pubsub::api::Topic::default(); + t.name = topic_name.clone().into(); + t }) .await?; println!("Creating subscription {}", &subscription_name); subscriber - .create_subscription(pubsub::api::Subscription { - name: subscription_name.clone().into(), - topic: topic_name.clone().into(), - ..pubsub::api::Subscription::default() + .raw_api_mut() + .create_subscription({ + let mut s = pubsub::api::Subscription::default(); + s.name = subscription_name.clone().into(); + s.topic = topic_name.clone().into(); + s }) .await?; println!("Publishing messages to topic"); - futures::stream::iter(0u32..100) - .map(|i| pubsub::api::PubsubMessage { - data: format!("message-{}", i).into(), - ..pubsub::api::PubsubMessage::default() + futures::stream::iter(0u32..15) + .map(|i| { + let mut m = pubsub::api::PubsubMessage::default(); + let payload = format!("message-{:02}", i); + println!("Sending `{payload}`"); + m.data = payload.into(); + m }) .map(Ok) - .forward(publisher.publish_topic_sink(topic_name.clone())) + .forward(publisher.publish_topic_sink(topic_name.clone(), pubsub::PublishConfig::default())) .await?; println!("Reading back published messages"); @@ -93,32 +100,49 @@ async fn main() -> Result<(), Box> { ); futures::pin_mut!(read_stream); - for i in 0u32..100 { + let mut messages = Vec::new(); + for _ in 0u32..15 { let (ack_token, message) = read_stream .next() .await .ok_or("unexpected end of stream")??; - ack_token.ack().await?; + let payload = std::str::from_utf8(&message.data[..]).unwrap(); + println!("Received `{payload}`"); + messages.push(payload.to_owned()); - assert_eq!(message.data, format!("message-{}", i)); + ack_token.ack().await?; } + messages.sort(); + assert_eq!( + messages, + (0..15) + .map(|i| format!("message-{:02}", i)) + .collect::>() + ); + println!("All messages matched!"); println!("Deleting subscription {}", &subscription_name); subscriber - .delete_subscription(pubsub::api::DeleteSubscriptionRequest { - subscription: subscription_name.into(), + .raw_api_mut() + .delete_subscription({ + let mut d = pubsub::api::DeleteSubscriptionRequest::default(); + d.subscription = subscription_name.into(); + d }) .await?; println!("Deleting topic {}", &topic_name); publisher - .delete_topic(pubsub::api::DeleteTopicRequest { - topic: topic_name.into(), + .raw_api_mut() + .delete_topic({ + let mut d = pubsub::api::DeleteTopicRequest::default(); + d.topic = topic_name.into(); + d }) .await?; diff --git a/generators/Cargo.toml b/generators/Cargo.toml index 782e5d0..c0cb939 100644 --- a/generators/Cargo.toml +++ b/generators/Cargo.toml @@ -16,12 +16,12 @@ harness = false [dependencies] anyhow = "1" flate2 = "1" -prost-build = { version = "0.11", features = ["format"] } +prost-build = { version = "0.12.3", features = ["format"] } reqwest = { version = "0.11", features = ["blocking"] } structopt = "0.3" tar = "0.4" tempfile = "3" -tonic-build = "0.9" +tonic-build = "0.10" [dev-dependencies] criterion = { version = "0.3", features = ["html_reports"] } diff --git a/generators/src/grpc.rs b/generators/src/grpc.rs index 4f74346..a6bc095 100644 --- a/generators/src/grpc.rs +++ b/generators/src/grpc.rs @@ -44,21 +44,36 @@ fn main() -> Result<(), Error> { // the wire prost_config.bytes(&["."]); - // The bigtable docs have doc comments that trigger test failures. - // (TODO: in newer versions of prost-build, the `format` option might be enough for this) - prost_config.disable_comments(&[ + // Some docs have doc comments that trigger test failures because they're not actually rust. + // Maybe future codegen will be better? + // Try to keep some docs by pretending the fields don't exist during doctests + for ignored_field in [ "bigtable.v2.RowFilter.Interleave.filters", + "bigtable.v2.ReadRowsRequest.reversed", + ] { + prost_config.field_attribute(ignored_field, "#[cfg(not(doctest))]"); + } + + // Other types can't be pretended away because typechecks will fail. just disable the comments + prost_config.disable_comments(&[ "bigtable.v2.RowFilter.sink", "iam.v1.Policy", "iam.v1.AuditConfig", "iam.v1.AuditLogConfig", - "type.Expr", ]); // the attributes map tend to have a small number of string keys, which are faster to access // using a btree than a hashmap. See the crate's benchmarks prost_config.btree_map(&["PubsubMessage.attributes"]); + // Declare all the generated structs and enums as non_exhaustive. + // + // This helps to reconcile two distinct semver conventions: + // 1. in protobuf, adding fields is a semver minor change + // 2. in prost codegen, structs are composed of all-pub fields, therefore adding a new field is + // a semver *major* change + prost_config.type_attribute(".", "#[non_exhaustive]"); + tonic_build::configure() .build_client(true) .build_server(false) diff --git a/src/auth/grpc.rs b/src/auth/grpc.rs index dcfbe26..1613b03 100644 --- a/src/auth/grpc.rs +++ b/src/auth/grpc.rs @@ -1,5 +1,6 @@ //! Authorization support for gRPC requests +use crate::auth::Auth; use futures::future::BoxFuture; use std::{ sync::Arc, @@ -45,15 +46,15 @@ use tonic::client::GrpcService; /// # }; /// ``` #[derive(Clone)] -pub struct AuthGrpcService { +pub struct AuthGrpcService { inner: Service, - auth: Option>, - scopes: Arc>, + auth: Option, + scopes: Arc<[String]>, } -impl AuthGrpcService { +impl AuthGrpcService { /// Wrap the given service to add authorization headers to each request - pub fn new(service: Service, auth: Option>, scopes: Vec) -> Self + pub fn new(service: Service, auth: Option, scopes: Vec) -> Self where // Generic bounds included on the constructor because having them only on the trait impl // doesn't produce good compiler diagnostics @@ -63,7 +64,7 @@ impl AuthGrpcService { Self { inner: service, auth, - scopes: Arc::new(scopes), + scopes: Arc::from(scopes), } } } @@ -93,20 +94,11 @@ where Grpc(ServiceErr), } -impl GrpcService for AuthGrpcService +impl GrpcService for AuthGrpcService where Service: GrpcService + Clone + Send + 'static, Service::Error: std::error::Error + Send + Sync + 'static, Service::Future: Send, - C: tower::Service + Clone + Send + Sync + 'static, - C::Response: hyper::client::connect::Connection - + tokio::io::AsyncRead - + tokio::io::AsyncWrite - + Send - + Unpin - + 'static, - C::Future: Send + Unpin + 'static, - C::Error: Into>, ReqBody: Send + 'static, { type Error = AuthGrpcError; @@ -290,8 +282,7 @@ mod test { } } - let mut auth_service = - AuthGrpcService::<_, crate::DefaultConnector>::new(OkService, None, vec![]); + let mut auth_service = AuthGrpcService::<_>::new(OkService, None, vec![]); let result = auth_service.call(http::request::Request::new(())).await; diff --git a/src/auth/mod.rs b/src/auth/mod.rs index e0aa1d0..5828279 100644 --- a/src/auth/mod.rs +++ b/src/auth/mod.rs @@ -3,6 +3,10 @@ #[cfg(feature = "grpc")] pub mod grpc; +pub(crate) type Auth = yup_oauth2::authenticator::Authenticator< + hyper_rustls::HttpsConnector, +>; + /// Add the given authorization token to the given HTTP request /// /// Returns an error if the token cannot form a valid HTTP header value. diff --git a/src/bigtable/admin.rs b/src/bigtable/admin.rs index cba220d..11032bf 100644 --- a/src/bigtable/admin.rs +++ b/src/bigtable/admin.rs @@ -1,12 +1,11 @@ //! An API for administering bigtable. +use super::api::bigtable::admin; use crate::{ - auth::grpc::{self, AuthGrpcService}, builder, + grpc::{Body, BoxBody, Bytes, DefaultGrpcImpl, GrpcService, StdError}, }; -use super::api::bigtable::admin; - pub use admin::v2::Table; use futures::Stream; @@ -17,7 +16,6 @@ const BIGTABLE_ADMIN_SCOPE: &'static str = "https://www.googleapis.com/auth/bigt config_default! { /// Configuration for the bigtable admin client #[derive(Debug, Clone, Eq, PartialEq, Hash, serde::Deserialize)] - #[non_exhaustive] pub struct BigtableTableAdminConfig { /// Endpoint to connect to bigtable over. @default("https://bigtableadmin.googleapis.com".into(), "BigtableTableAdminConfig::default_endpoint") @@ -29,10 +27,8 @@ config_default! { /// [`build_bigtable_client`](crate::builder::ClientBuilder::build_bigtable_client) /// function. #[derive(Clone)] -pub struct BigtableTableAdminClient { - pub(crate) inner: admin::v2::bigtable_table_admin_client::BigtableTableAdminClient< - AuthGrpcService, - >, +pub struct BigtableTableAdminClient { + pub(crate) inner: admin::v2::bigtable_table_admin_client::BigtableTableAdminClient, // A string of the form projects/{project}/instances/{instance} pub(crate) table_prefix: String, } @@ -73,30 +69,53 @@ impl From for admin::v2::GcRule { } } -impl BigtableTableAdminClient +impl BigtableTableAdminClient { + /// Manually construct a new client. + /// + /// There are limited circumstances in which this is useful; consider instead using the builder + /// function [crate::builder::ClientBuilder::build_bigtable_admin_client] + pub fn from_raw_api( + client: admin::v2::bigtable_table_admin_client::BigtableTableAdminClient, + project: &str, + instance_name: &str, + ) -> Self { + BigtableTableAdminClient { + inner: client, + table_prefix: format!("projects/{}/instances/{}", project, instance_name), + } + } + + /// Access the underlying grpc api + pub fn raw_api(&self) -> &admin::v2::bigtable_table_admin_client::BigtableTableAdminClient { + &self.inner + } + + /// Mutably access the underlying grpc api + pub fn raw_api_mut( + &mut self, + ) -> &mut admin::v2::bigtable_table_admin_client::BigtableTableAdminClient { + &mut self.inner + } +} + +impl BigtableTableAdminClient where - C: tower::Service + Clone + Send + Sync + 'static, - C::Response: hyper::client::connect::Connection - + tokio::io::AsyncRead - + tokio::io::AsyncWrite - + Send - + Unpin - + 'static, - C::Future: Send + Unpin + 'static, - C::Error: Into>, + S: GrpcService, + S::Error: Into, + S::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, { /// Create a new table. pub async fn create_table( &mut self, - table_name: &str, + table_name: impl Into, column_families: Fams, ) -> Result where Fams: IntoIterator, { - let table_id = table_name.to_owned(); + let table_id = table_name.into(); let table = Table { - name: format!("{}/tables/{}", self.table_prefix, table_name), column_families: column_families .into_iter() .map(|(name, rule)| { @@ -121,19 +140,32 @@ where Ok(response.into_inner()) } - /// List all tables. + /// List all tables belonging to this project and instance. pub async fn list_tables( &mut self, - ) -> Result>, tonic::Status> { - let req = admin::v2::ListTablesRequest { - parent: self.table_prefix.clone(), - ..Default::default() - }; - let response = self.inner.list_tables(req).await?; - // TODO: if the response was paged, make a follow-up request. - Ok(futures::stream::iter( - response.into_inner().tables.into_iter().map(|x| Ok(x)), - )) + ) -> Result> + '_, tonic::Status> { + Ok(async_stream::stream! { + let mut page_token = String::new(); + loop { + let req = admin::v2::ListTablesRequest { + parent: self.table_prefix.clone(), + page_token, + ..Default::default() + }; + let response = self.inner.list_tables(req).await?.into_inner(); + + for table in response.tables.into_iter() { + yield Ok(table); + } + + if response.next_page_token.is_empty() { + break; + } else { + page_token = response.next_page_token; + continue; + } + } + }) } } @@ -142,41 +174,27 @@ where #[error(transparent)] pub struct BuildError(#[from] tonic::transport::Error); -impl builder::ClientBuilder -where - C: tower::Service + Clone + Send + Sync + 'static, - C::Response: hyper::client::connect::Connection - + tokio::io::AsyncRead - + tokio::io::AsyncWrite - + Send - + Unpin - + 'static, - C::Future: Send + Unpin + 'static, - C::Error: Into>, - Box: From, -{ +impl builder::ClientBuilder { /// Create a client for administering bigtable tables. pub async fn build_bigtable_admin_client( &self, config: BigtableTableAdminConfig, project: &str, instance_name: &str, - ) -> Result, BuildError> { + ) -> Result, BuildError> { let scopes = vec![BIGTABLE_ADMIN_SCOPE.to_owned()]; let endpoint = tonic::transport::Endpoint::new(config.endpoint)?; - let connection = endpoint - .connect_with_connector(self.connector.clone()) - .await?; - let table_prefix = format!("projects/{}/instances/{}", project, instance_name); + let connection = endpoint.connect().await?; let inner = admin::v2::bigtable_table_admin_client::BigtableTableAdminClient::new( - grpc::AuthGrpcService::new(connection, self.auth.clone(), scopes), + DefaultGrpcImpl::new(connection, self.auth.clone(), scopes), ); - Ok(BigtableTableAdminClient { + Ok(BigtableTableAdminClient::from_raw_api( inner, - table_prefix, - }) + project, + instance_name, + )) } } diff --git a/src/bigtable/client_builder.rs b/src/bigtable/client_builder.rs index 9bd497b..30993fd 100644 --- a/src/bigtable/client_builder.rs +++ b/src/bigtable/client_builder.rs @@ -1,8 +1,6 @@ use crate::{ - auth::grpc, bigtable::{api, BigtableClient}, - builder, - retry_policy::{exponential_backoff, ExponentialBackoff}, + builder, grpc, }; const BIGTABLE_DATA_SCOPE: &'static str = "https://www.googleapis.com/auth/bigtable.data"; @@ -17,7 +15,6 @@ const MAX_MESSAGE_SIZE: usize = usize::MAX; config_default! { /// Configuration for connecting to bigtable #[derive(Debug, Clone, Eq, PartialEq, Hash, serde::Deserialize)] - #[non_exhaustive] pub struct BigtableConfig { /// Endpoint to connect to bigtable over. @default("https://bigtable.googleapis.com".into(), "BigtableConfig::default_endpoint") @@ -44,48 +41,24 @@ impl BigtableConfig { #[error(transparent)] pub struct BuildError(#[from] tonic::transport::Error); -use super::BigtableRetryCheck; - -impl builder::ClientBuilder -where - C: tower::Service + Clone + Send + Sync + 'static, - C::Response: hyper::client::connect::Connection - + tokio::io::AsyncRead - + tokio::io::AsyncWrite - + Send - + Unpin - + 'static, - C::Future: Send + Unpin + 'static, - C::Error: Into>, - Box: From, -{ +impl builder::ClientBuilder { /// Create a client for connecting to bigtable pub async fn build_bigtable_client( &self, config: BigtableConfig, project: &str, instance_name: &str, - ) -> Result, BuildError> { + ) -> Result, BuildError> { let scopes = config.auth_scopes(); let endpoint = tonic::transport::Endpoint::new(config.endpoint)?; - let connection = endpoint - .connect_with_connector(self.connector.clone()) - .await?; - let table_prefix = format!("projects/{}/instances/{}/tables/", project, instance_name); + let connection = endpoint.connect().await?; let inner = api::bigtable::v2::bigtable_client::BigtableClient::new( - grpc::AuthGrpcService::new(connection, self.auth.clone(), scopes), + grpc::DefaultGrpcImpl::new(connection, self.auth.clone(), scopes), ) .max_decoding_message_size(MAX_MESSAGE_SIZE); - Ok(BigtableClient { - inner, - table_prefix, - retry: ExponentialBackoff::new( - BigtableRetryCheck::default(), - exponential_backoff::Config::default(), - ), - }) + Ok(BigtableClient::from_raw_api(inner, project, instance_name)) } } diff --git a/src/bigtable/mod.rs b/src/bigtable/mod.rs index 2ae2510..cdf1540 100644 --- a/src/bigtable/mod.rs +++ b/src/bigtable/mod.rs @@ -5,13 +5,14 @@ //! allows for creating and listing tables. use futures::prelude::*; -use hyper::body::Bytes; -use prost::bytes::BytesMut; +use prost::bytes::{Bytes, BytesMut}; use std::ops::{Bound, RangeBounds}; use crate::{ - auth::grpc::AuthGrpcService, - retry_policy::{ExponentialBackoff, RetryOperation, RetryPolicy, RetryPredicate}, + grpc::{Body, BoxBody, DefaultGrpcImpl, GrpcService, StdError}, + retry_policy::{ + exponential_backoff, ExponentialBackoff, RetryOperation, RetryPolicy, RetryPredicate, + }, }; pub use http::Uri; @@ -367,28 +368,63 @@ impl From for ReadRowsError { /// [`build_bigtable_client`](crate::builder::ClientBuilder::build_bigtable_client) /// function. #[derive(Clone)] -pub struct BigtableClient< - C = crate::DefaultConnector, - Retry = ExponentialBackoff, -> { - inner: api::bigtable::v2::bigtable_client::BigtableClient< - AuthGrpcService, - >, +pub struct BigtableClient> { + inner: api::bigtable::v2::bigtable_client::BigtableClient, retry: Retry, table_prefix: String, } -impl BigtableClient +impl BigtableClient { + /// Manually construct a new client. + /// + /// There are limited circumstances in which this is useful; consider instead using the builder + /// function [crate::builder::ClientBuilder::build_bigtable_client] + pub fn from_raw_api( + client: api::bigtable::v2::bigtable_client::BigtableClient, + project: &str, + instance_name: &str, + ) -> Self { + BigtableClient { + inner: client, + retry: ExponentialBackoff::new( + BigtableRetryCheck::default(), + exponential_backoff::Config::default(), + ), + table_prefix: format!("projects/{}/instances/{}/tables/", project, instance_name), + } + } +} + +impl BigtableClient { + /// Set the retry policy for failed operations encountered by this client + pub fn with_retry_policy(self, retry_policy: Retry) -> BigtableClient + where + Retry: RetryPolicy<(), tonic::Status> + 'static, + { + BigtableClient { + inner: self.inner, + retry: retry_policy, + table_prefix: self.table_prefix, + } + } + + /// Access the underlying grpc api + pub fn raw_api(&self) -> &api::bigtable::v2::bigtable_client::BigtableClient { + &self.inner + } + + /// Mutably access the underlying grpc api + pub fn raw_api_mut(&mut self) -> &mut api::bigtable::v2::bigtable_client::BigtableClient { + &mut self.inner + } +} + +impl BigtableClient where - C: tower::Service + Clone + Send + Sync + 'static, - C::Response: hyper::client::connect::Connection - + tokio::io::AsyncRead - + tokio::io::AsyncWrite - + Send - + Unpin - + 'static, - C::Future: Send + Unpin + 'static, - C::Error: Into>, + S: GrpcService, + S::Error: Into, + S::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, Retry: RetryPolicy<(), tonic::Status> + 'static, Retry::RetryOp: Send + 'static, >::Sleep: Send + 'static, diff --git a/src/builder.rs b/src/builder.rs index 7f2d71d..7a7614c 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -2,12 +2,9 @@ //! //! See [`ClientBuilder`], which is used to instantiate the various GCP service clients. +use crate::auth::Auth; use std::path::PathBuf; -use hyper::client::Client; - -use crate::Auth; - const SERVICE_ACCOUNT_ENV_VAR: &str = "GOOGLE_APPLICATION_CREDENTIALS"; /// Configuration for loading service account credentials from file @@ -69,7 +66,6 @@ impl Default for AuthFlow { config_default! { /// Configuration for creating a [`ClientBuilder`] #[derive(Debug, Clone, serde::Deserialize)] - #[non_exhaustive] pub struct ClientBuilderConfig { /// How authentication credentials should be loaded @default(AuthFlow::ServiceAccount(ServiceAccountAuth::EnvVar), "ClientBuilderConfig::default_auth_flow") @@ -105,98 +101,62 @@ pub enum CreateBuilderError { Connector(#[source] Box), } -// Set a default connector if a connector feature is enabled. -// -// This is default is then used as a default type for the generic parameter on types throughout -// this crate. Using this default is more ergonomic than specifying a generic type everywhere, -// which suits this crate's goal of ease-of-use -cfg_if::cfg_if! { - // the order of the checked features has potentially user-facing consequences: "rustls" is - // currently enabled in default features, so "openssl" should be checked in this if-chain - // before it, so that `features = ["openssl"]` will do the less surprising thing (use openssl) - // despite having rustls and openssl both enabled. This allows a user to forget - // `default-features = false` with hopefully fewer unexpected consequences - - if #[cfg(feature="openssl")] { - /// The default connector used for clients, based on the crate's enabled features - pub type DefaultConnector = - hyper_openssl::HttpsConnector; - - impl ClientBuilder { - /// Create a new client builder using the default HTTPS connector based on the crate's - /// enabled features - #[cfg_attr(docsrs, doc(cfg(any(feature="rustls", feature="openssl"))))] - pub async fn new(config: ClientBuilderConfig) -> Result { - let connector = hyper_openssl::HttpsConnector::new() - .map_err(|e| CreateBuilderError::Connector(e.into()))?; - - Self::with_connector(config, connector).await - } - } - } - else if #[cfg(feature="rustls")] { - /// The default connector used for clients, based on the crate's enabled features - pub type DefaultConnector = - hyper_rustls::HttpsConnector; - - impl ClientBuilder { - /// Create a new client builder using the default HTTPS connector based on the crate's - /// enabled features - #[cfg_attr(docsrs, doc(cfg(any(feature="rustls", feature="openssl"))))] - pub async fn new(config: ClientBuilderConfig) -> Result { - let connector = hyper_rustls::HttpsConnector::with_native_roots(); - - Self::with_connector(config, connector).await - } - } - } - else { - // If no connector features are enabled, the default connector can be any type. The type - // may show up in errors if a user forgets to specify the generic, however, so it's useful - // to have the type's name document the user's issue +type Client = hyper::client::Client>; - #[doc(hidden)] - pub struct NoConnectorFeaturesEnabled; +#[allow(unused)] // only used by some feature combinations +pub(crate) fn https_connector() -> hyper_rustls::HttpsConnector { + #[allow(unused_mut)] + let mut roots = rustls::RootCertStore::empty(); - /// The default connector used for clients, based on the crate's enabled features - pub type DefaultConnector = NoConnectorFeaturesEnabled; - } + #[cfg(feature = "rustls-native-certs")] + roots.add_parsable_certificates( + &rustls_native_certs::load_native_certs().expect("could not load native certs"), + ); + + #[cfg(feature = "webpki-roots")] + roots.add_trust_anchors(webpki_roots::TLS_SERVER_ROOTS.iter().map(|ta| { + rustls::OwnedTrustAnchor::from_subject_spki_name_constraints( + ta.subject, + ta.spki, + ta.name_constraints, + ) + })); + + let tls_config = rustls::client::ClientConfig::builder() + .with_safe_defaults() + .with_root_certificates(roots) + .with_no_client_auth(); + + hyper_rustls::HttpsConnectorBuilder::new() + .with_tls_config(tls_config) + .https_or_http() + .enable_all_versions() + .build() } /// A builder used to create all the clients for interacting with GCP services. /// /// Note that the builder is not consumed when creating clients, and many clients can be built /// using the same builder. This may allow some resource re-use across the clients -pub struct ClientBuilder { - // not all features use all the fields. Suppress the unused warning for simplicity - #[allow(unused)] - pub(crate) connector: Connector, - #[allow(unused)] - pub(crate) auth: Option>, +pub struct ClientBuilder { #[allow(unused)] - pub(crate) client: Client, + pub(crate) auth: Option, } -impl ClientBuilder { - /// Create a new client builder using the given connector - pub async fn with_connector( +impl ClientBuilder { + /// Create a new client builder using default HTTPS settings + #[cfg(any(feature = "rustls-native-certs", feature = "webpki-roots"))] + pub async fn new(config: ClientBuilderConfig) -> Result { + Self::with_auth_connector(config, https_connector).await + } + + /// Create a new client builder using the given connector for authentication requests + pub async fn with_auth_connector( config: ClientBuilderConfig, - connector: C, - ) -> Result - where - C: hyper::service::Service + Clone + Send + Sync + 'static, - C::Response: hyper::client::connect::Connection - + tokio::io::AsyncRead - + tokio::io::AsyncWrite - + Send - + Unpin - + 'static, - C::Future: Send + Unpin + 'static, - C::Error: Into>, - { + connector_fn: impl FnOnce() -> hyper_rustls::HttpsConnector, + ) -> Result { use AuthFlow::{NoAuth, ServiceAccount, ServiceAccountImpersonation, UserAccount}; - - let client = hyper::client::Client::builder().build(connector.clone()); + let make_client = move || hyper::client::Client::builder().build(connector_fn()); let auth = match config.auth_flow { NoAuth => None, @@ -210,67 +170,28 @@ impl ClientBuilder { ), ServiceAccountAuth::ApplicationDefault => None, }, - client.clone(), + make_client(), ) .await?, ), ServiceAccountImpersonation { user, email } => Some( - create_service_impersonation_auth(user.into_os_string(), email, client.clone()) + create_service_impersonation_auth(user.into_os_string(), email, make_client()) .await?, ), UserAccount(path) => { - Some(create_user_auth(path.into_os_string(), client.clone()).await?) + Some(create_user_auth(path.into_os_string(), make_client()).await?) } }; - Ok(Self { - connector, - client, - auth, - }) - } - - /// Create a new client builder with the given connector and auth builder. - pub async fn with_connector_and_auth_builder( - connector: C, - auth_builder: impl FnOnce(Client) -> F, - ) -> Result - where - C: crate::Connect + Clone + Send + Sync + 'static, - F: futures::Future>>, - { - let client = hyper::client::Client::builder().build(connector.clone()); - - let auth = Some( - auth_builder(client.clone()) - .await - .map_err(CreateBuilderError::Authenticator)?, - ); - - Ok(Self { - connector, - client, - auth, - }) + Ok(Self { auth }) } } /// Convenience method to create an Authorization for the oauth ServiceFlow. -async fn create_service_auth( +async fn create_service_auth( service_account_key_path: Option>, - client: Client, -) -> Result, CreateBuilderError> -where - C: hyper::service::Service + Clone + Send + Sync + 'static, - C::Response: hyper::client::connect::Connection - + tokio::io::AsyncRead - + tokio::io::AsyncWrite - + Send - + Unpin - + 'static, - C::Future: Send + Unpin + 'static, - C::Error: Into>, -{ + client: Client, +) -> Result { match service_account_key_path { Some(service_account_key_path) => { let service_account_key = @@ -310,21 +231,10 @@ where } } -async fn create_user_auth( +async fn create_user_auth( user_secrets_path: impl AsRef, - client: Client, -) -> Result, CreateBuilderError> -where - C: hyper::service::Service + Clone + Send + Sync + 'static, - C::Response: hyper::client::connect::Connection - + tokio::io::AsyncRead - + tokio::io::AsyncWrite - + Send - + Unpin - + 'static, - C::Future: Send + Unpin + 'static, - C::Error: Into>, -{ + client: Client, +) -> Result { let user_secret = yup_oauth2::read_authorized_user_secret(user_secrets_path.as_ref()) .await .map_err(|e| { @@ -337,22 +247,11 @@ where .map_err(CreateBuilderError::Authenticator) } -async fn create_service_impersonation_auth( +async fn create_service_impersonation_auth( user_secrets_path: impl AsRef, email: String, - client: Client, -) -> Result, CreateBuilderError> -where - C: hyper::service::Service + Clone + Send + Sync + 'static, - C::Response: hyper::client::connect::Connection - + tokio::io::AsyncRead - + tokio::io::AsyncWrite - + Send - + Unpin - + 'static, - C::Future: Send + Unpin + 'static, - C::Error: Into>, -{ + client: Client, +) -> Result { let user_secret = yup_oauth2::read_authorized_user_secret(user_secrets_path.as_ref()) .await .map_err(|e| { diff --git a/src/generated/google.api.rs b/src/generated/google.api.rs index 42caf16..84e317c 100644 --- a/src/generated/google.api.rs +++ b/src/generated/google.api.rs @@ -1,6 +1,7 @@ /// Defines the HTTP configuration for an API service. It contains a list of -/// \[HttpRule][google.api.HttpRule\], each specifying the mapping of an RPC method +/// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method /// to one or more HTTP REST API methods. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Http { @@ -26,7 +27,7 @@ pub struct Http { /// APIs](), /// [Cloud Endpoints](), [gRPC /// Gateway](), -/// and \[Envoy\]() proxy support this feature +/// and [Envoy]() proxy support this feature /// and use it for large scale production services. /// /// `HttpRule` defines the schema of the gRPC/REST mapping. The mapping specifies @@ -187,26 +188,26 @@ pub struct Http { /// 1. Leaf request fields (recursive expansion nested messages in the request /// message) are classified into three categories: /// - Fields referred by the path template. They are passed via the URL path. -/// - Fields referred by the \[HttpRule.body][google.api.HttpRule.body\]. They +/// - Fields referred by the [HttpRule.body][google.api.HttpRule.body]. They /// are passed via the HTTP /// request body. /// - All other fields are passed via the URL query parameters, and the /// parameter name is the field path in the request message. A repeated /// field can be represented as multiple query parameters under the same /// name. -/// 2. If \[HttpRule.body][google.api.HttpRule.body\] is "*", there is no URL +/// 2. If [HttpRule.body][google.api.HttpRule.body] is "*", there is no URL /// query parameter, all fields /// are passed via URL path and HTTP request body. -/// 3. If \[HttpRule.body][google.api.HttpRule.body\] is omitted, there is no HTTP +/// 3. If [HttpRule.body][google.api.HttpRule.body] is omitted, there is no HTTP /// request body, all /// fields are passed via URL path and URL query parameters. /// /// ### Path template syntax /// -/// Template = "/" Segments [ Verb ] ; +/// Template = "/" Segments \[ Verb \] ; /// Segments = Segment { "/" Segment } ; /// Segment = "*" | "**" | LITERAL | Variable ; -/// Variable = "{" FieldPath [ "=" Segments ] "}" ; +/// Variable = "{" FieldPath \[ "=" Segments \] "}" ; /// FieldPath = IDENT { "." IDENT } ; /// Verb = ":" LITERAL ; /// @@ -290,12 +291,13 @@ pub struct Http { /// If an API needs to use a JSON array for request or response body, it can map /// the request or response body to a repeated field. However, some gRPC /// Transcoding implementations may not support this feature. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct HttpRule { /// Selects a method to which this rule applies. /// - /// Refer to \[selector][google.api.DocumentationRule.selector\] for syntax + /// Refer to [selector][google.api.DocumentationRule.selector] for syntax /// details. #[prost(string, tag = "1")] pub selector: ::prost::alloc::string::String, @@ -331,6 +333,7 @@ pub mod http_rule { /// Determines the URL pattern is matched by this rules. This pattern can be /// used with any of the {get|put|post|delete|patch} methods. A custom method /// can be defined using the 'custom' field. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Pattern { @@ -359,6 +362,7 @@ pub mod http_rule { } } /// A custom pattern is used for defining custom HTTP verb. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CustomHttpPattern { @@ -371,6 +375,7 @@ pub struct CustomHttpPattern { } /// The launch stage as defined by [Google Cloud Platform /// Launch Stages](). +#[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum LaunchStage { @@ -445,6 +450,7 @@ impl LaunchStage { } } /// Required information for every language. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CommonLanguageSettings { @@ -458,6 +464,7 @@ pub struct CommonLanguageSettings { pub destinations: ::prost::alloc::vec::Vec, } /// Details about how and where to publish client libraries. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ClientLibrarySettings { @@ -501,6 +508,7 @@ pub struct ClientLibrarySettings { /// This message configures the settings for publishing [Google Cloud Client /// libraries]() /// generated from the service config. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Publishing { @@ -508,7 +516,7 @@ pub struct Publishing { /// long-running operation pattern. #[prost(message, repeated, tag = "2")] pub method_settings: ::prost::alloc::vec::Vec, - /// Link to a place that API users can report issues. Example: + /// Link to a *public* URI where users can report issues. Example: /// #[prost(string, tag = "101")] pub new_issue_uri: ::prost::alloc::string::String, @@ -546,6 +554,7 @@ pub struct Publishing { pub proto_reference_documentation_uri: ::prost::alloc::string::String, } /// Settings for Java client libraries. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct JavaSettings { @@ -586,6 +595,7 @@ pub struct JavaSettings { pub common: ::core::option::Option, } /// Settings for C++ client libraries. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CppSettings { @@ -594,6 +604,7 @@ pub struct CppSettings { pub common: ::core::option::Option, } /// Settings for Php client libraries. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PhpSettings { @@ -602,6 +613,7 @@ pub struct PhpSettings { pub common: ::core::option::Option, } /// Settings for Python client libraries. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PythonSettings { @@ -610,6 +622,7 @@ pub struct PythonSettings { pub common: ::core::option::Option, } /// Settings for Node client libraries. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct NodeSettings { @@ -618,6 +631,7 @@ pub struct NodeSettings { pub common: ::core::option::Option, } /// Settings for Dotnet client libraries. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DotnetSettings { @@ -664,6 +678,7 @@ pub struct DotnetSettings { pub handwritten_signatures: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, } /// Settings for Ruby client libraries. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RubySettings { @@ -672,6 +687,7 @@ pub struct RubySettings { pub common: ::core::option::Option, } /// Settings for Go client libraries. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GoSettings { @@ -680,6 +696,7 @@ pub struct GoSettings { pub common: ::core::option::Option, } /// Describes the generator configuration for a method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MethodSettings { @@ -713,7 +730,8 @@ pub mod method_settings { /// long-running operation pattern. /// All default values below are from those used in the client library /// generators (e.g. - /// \[Java\]()). + /// [Java]()). + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct LongRunning { @@ -738,6 +756,7 @@ pub mod method_settings { } /// The organization for which the client libraries are being published. /// Affects the url where generated docs are published, etc. +#[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum ClientLibraryOrganization { @@ -751,6 +770,12 @@ pub enum ClientLibraryOrganization { Photos = 3, /// Street View Org. StreetView = 4, + /// Shopping Org. + Shopping = 5, + /// Geo Org. + Geo = 6, + /// Generative AI - + GenerativeAi = 7, } impl ClientLibraryOrganization { /// String value of the enum field names used in the ProtoBuf definition. @@ -766,6 +791,9 @@ impl ClientLibraryOrganization { ClientLibraryOrganization::Ads => "ADS", ClientLibraryOrganization::Photos => "PHOTOS", ClientLibraryOrganization::StreetView => "STREET_VIEW", + ClientLibraryOrganization::Shopping => "SHOPPING", + ClientLibraryOrganization::Geo => "GEO", + ClientLibraryOrganization::GenerativeAi => "GENERATIVE_AI", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -776,11 +804,15 @@ impl ClientLibraryOrganization { "ADS" => Some(Self::Ads), "PHOTOS" => Some(Self::Photos), "STREET_VIEW" => Some(Self::StreetView), + "SHOPPING" => Some(Self::Shopping), + "GEO" => Some(Self::Geo), + "GENERATIVE_AI" => Some(Self::GenerativeAi), _ => None, } } } /// To where should client libraries be published? +#[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum ClientLibraryDestination { @@ -823,6 +855,7 @@ impl ClientLibraryDestination { /// denotes the behavior and may affect how API tooling handles the field. /// /// Note: This enum **may** receive new values in the future. +#[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum FieldBehavior { @@ -859,6 +892,19 @@ pub enum FieldBehavior { /// a non-empty value will be returned. The user will not be aware of what /// non-empty value to expect. NonEmptyDefault = 7, + /// Denotes that the field in a resource (a message annotated with + /// google.api.resource) is used in the resource name to uniquely identify the + /// resource. For AIP-compliant APIs, this should only be applied to the + /// `name` field on the resource. + /// + /// This behavior should not be applied to references to other resources within + /// the message. + /// + /// The identifier field of resources often have different field behavior + /// depending on the request it is embedded in (e.g. for Create methods name + /// is optional and unused, while for Update methods it is required). Instead + /// of method-specific annotations, only `IDENTIFIER` is required. + Identifier = 8, } impl FieldBehavior { /// String value of the enum field names used in the ProtoBuf definition. @@ -875,6 +921,7 @@ impl FieldBehavior { FieldBehavior::Immutable => "IMMUTABLE", FieldBehavior::UnorderedList => "UNORDERED_LIST", FieldBehavior::NonEmptyDefault => "NON_EMPTY_DEFAULT", + FieldBehavior::Identifier => "IDENTIFIER", } } /// Creates an enum from field names used in the ProtoBuf definition. @@ -888,6 +935,7 @@ impl FieldBehavior { "IMMUTABLE" => Some(Self::Immutable), "UNORDERED_LIST" => Some(Self::UnorderedList), "NON_EMPTY_DEFAULT" => Some(Self::NonEmptyDefault), + "IDENTIFIER" => Some(Self::Identifier), _ => None, } } @@ -939,6 +987,7 @@ impl FieldBehavior { /// pattern: "folders/{folder}/logs/{log}" /// pattern: "organizations/{organization}/logs/{log}" /// pattern: "billingAccounts/{billing_account}/logs/{log}" +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ResourceDescriptor { @@ -949,7 +998,7 @@ pub struct ResourceDescriptor { /// Example: `storage.googleapis.com/Bucket` /// /// The value of the resource_type_kind must follow the regular expression - /// /\[A-Za-z][a-zA-Z0-9\]+/. It should start with an upper case character and + /// /[A-Za-z][a-zA-Z0-9]+/. It should start with an upper case character and /// should use PascalCase (UpperCamelCase). The maximum number of /// characters allowed for the `resource_type_kind` is 100. #[prost(string, tag = "1")] @@ -1021,6 +1070,7 @@ pub struct ResourceDescriptor { pub mod resource_descriptor { /// A description of the historical or future-looking state of the /// resource pattern. + #[non_exhaustive] #[derive( Clone, Copy, @@ -1067,6 +1117,7 @@ pub mod resource_descriptor { } } /// A flag representing a specific style that a resource claims to conform to. + #[non_exhaustive] #[derive( Clone, Copy, @@ -1115,6 +1166,7 @@ pub mod resource_descriptor { } /// Defines a proto annotation that describes a string field that refers to /// an API resource. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ResourceReference { @@ -1513,6 +1565,7 @@ pub struct ResourceReference { /// /// x-goog-request-params: /// table_location=instances/instance_bar&routing_id=prof_qux +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RoutingRule { @@ -1526,6 +1579,7 @@ pub struct RoutingRule { pub routing_parameters: ::prost::alloc::vec::Vec, } /// A projection from an input message to the GRPC or REST header. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RoutingParameter { diff --git a/src/generated/google.bigtable.admin.v2.rs b/src/generated/google.bigtable.admin.v2.rs index 494d090..6c0a186 100644 --- a/src/generated/google.bigtable.admin.v2.rs +++ b/src/generated/google.bigtable.admin.v2.rs @@ -1,5 +1,6 @@ /// Encapsulates progress related information for a Cloud Bigtable long /// running operation. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct OperationProgress { @@ -16,6 +17,7 @@ pub struct OperationProgress { pub end_time: ::core::option::Option<::prost_types::Timestamp>, } /// Storage media types for persisting Bigtable data. +#[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum StorageType { @@ -49,6 +51,7 @@ impl StorageType { } } /// Information about a table restore. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RestoreInfo { @@ -62,6 +65,7 @@ pub struct RestoreInfo { /// Nested message and enum types in `RestoreInfo`. pub mod restore_info { /// Information about the source used to restore the table. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum SourceInfo { @@ -71,13 +75,27 @@ pub mod restore_info { BackupInfo(super::BackupInfo), } } +/// Change stream configuration. +#[non_exhaustive] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ChangeStreamConfig { + /// How long the change stream should be retained. Change stream data older + /// than the retention period will not be returned when reading the change + /// stream from the table. + /// Values must be at least 1 day and at most 7 days, and will be truncated to + /// microsecond granularity. + #[prost(message, optional, tag = "1")] + pub retention_period: ::core::option::Option<::prost_types::Duration>, +} /// A collection of user data indexed by row, column, and timestamp. /// Each table is served using the resources of its parent cluster. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Table { /// The unique name of the table. Values are of the form - /// `projects/{project}/instances/{instance}/tables/\[_a-zA-Z0-9][-_.a-zA-Z0-9\]*`. + /// `projects/{project}/instances/{instance}/tables/[_a-zA-Z0-9][-_.a-zA-Z0-9]*`. /// Views: `NAME_ONLY`, `SCHEMA_VIEW`, `REPLICATION_VIEW`, `FULL` #[prost(string, tag = "1")] pub name: ::prost::alloc::string::String, @@ -92,27 +110,34 @@ pub struct Table { table::ClusterState, >, /// The column families configured for this table, mapped by column family ID. - /// Views: `SCHEMA_VIEW`, `FULL` + /// Views: `SCHEMA_VIEW`, `STATS_VIEW`, `FULL` #[prost(map = "string, message", tag = "3")] pub column_families: ::std::collections::HashMap< ::prost::alloc::string::String, ColumnFamily, >, - /// Immutable. The granularity (i.e. `MILLIS`) at which timestamps are stored in this - /// table. Timestamps not matching the granularity will be rejected. - /// If unspecified at creation time, the value will be set to `MILLIS`. - /// Views: `SCHEMA_VIEW`, `FULL`. + /// Immutable. The granularity (i.e. `MILLIS`) at which timestamps are stored + /// in this table. Timestamps not matching the granularity will be rejected. If + /// unspecified at creation time, the value will be set to `MILLIS`. Views: + /// `SCHEMA_VIEW`, `FULL`. #[prost(enumeration = "table::TimestampGranularity", tag = "4")] pub granularity: i32, - /// Output only. If this table was restored from another data source (e.g. a backup), this - /// field will be populated with information about the restore. + /// Output only. If this table was restored from another data source (e.g. a + /// backup), this field will be populated with information about the restore. #[prost(message, optional, tag = "6")] pub restore_info: ::core::option::Option, + /// If specified, enable the change stream on this table. + /// Otherwise, the change stream is disabled and the change stream is not + /// retained. + #[prost(message, optional, tag = "8")] + pub change_stream_config: ::core::option::Option, /// Set to true to make the table protected against data loss. i.e. deleting /// the following resources through Admin APIs are prohibited: - /// - The table. - /// - The column families in the table. - /// - The instance containing the table. + /// + /// * The table. + /// * The column families in the table. + /// * The instance containing the table. + /// /// Note one can still delete the data stored in the table through Data APIs. #[prost(bool, tag = "9")] pub deletion_protection: bool, @@ -120,6 +145,7 @@ pub struct Table { /// Nested message and enum types in `Table`. pub mod table { /// The state of a table's data in a particular cluster. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ClusterState { @@ -137,6 +163,7 @@ pub mod table { /// Nested message and enum types in `ClusterState`. pub mod cluster_state { /// Table replication states. + #[non_exhaustive] #[derive( Clone, Copy, @@ -202,6 +229,7 @@ pub mod table { } /// Possible timestamp granularities to use when keeping multiple versions /// of data in a table. + #[non_exhaustive] #[derive( Clone, Copy, @@ -242,6 +270,7 @@ pub mod table { } } /// Defines a view over a table's fields. + #[non_exhaustive] #[derive( Clone, Copy, @@ -299,6 +328,7 @@ pub mod table { } } /// A set of columns within a table which share a common configuration. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ColumnFamily { @@ -312,6 +342,7 @@ pub struct ColumnFamily { pub gc_rule: ::core::option::Option, } /// Rule for determining which cells to delete during garbage collection. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GcRule { @@ -322,6 +353,7 @@ pub struct GcRule { /// Nested message and enum types in `GcRule`. pub mod gc_rule { /// A GcRule which deletes cells matching all of the given rules. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Intersection { @@ -330,6 +362,7 @@ pub mod gc_rule { pub rules: ::prost::alloc::vec::Vec, } /// A GcRule which deletes cells matching any of the given rules. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Union { @@ -338,6 +371,7 @@ pub mod gc_rule { pub rules: ::prost::alloc::vec::Vec, } /// Garbage collection rules. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Rule { @@ -361,24 +395,27 @@ pub mod gc_rule { /// If this resource is protected with customer managed encryption, the in-use /// Cloud Key Management Service (Cloud KMS) key version is specified along with /// its status. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct EncryptionInfo { /// Output only. The type of encryption used to protect this resource. #[prost(enumeration = "encryption_info::EncryptionType", tag = "3")] pub encryption_type: i32, - /// Output only. The status of encrypt/decrypt calls on underlying data for this resource. - /// Regardless of status, the existing data is always encrypted at rest. + /// Output only. The status of encrypt/decrypt calls on underlying data for + /// this resource. Regardless of status, the existing data is always encrypted + /// at rest. #[prost(message, optional, tag = "4")] pub encryption_status: ::core::option::Option, - /// Output only. The version of the Cloud KMS key specified in the parent cluster that is - /// in use for the data underlying this table. + /// Output only. The version of the Cloud KMS key specified in the parent + /// cluster that is in use for the data underlying this table. #[prost(string, tag = "2")] pub kms_key_version: ::prost::alloc::string::String, } /// Nested message and enum types in `EncryptionInfo`. pub mod encryption_info { /// Possible encryption types for a resource. + #[non_exhaustive] #[derive( Clone, Copy, @@ -439,10 +476,11 @@ pub mod encryption_info { /// feature is not currently available to most Cloud Bigtable customers. This /// feature might be changed in backward-incompatible ways and is not recommended /// for production use. It is not subject to any SLA or deprecation policy. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Snapshot { - /// Output only. The unique name of the snapshot. + /// The unique name of the snapshot. /// Values are of the form /// `projects/{project}/instances/{instance}/clusters/{cluster}/snapshots/{snapshot}`. #[prost(string, tag = "1")] @@ -459,21 +497,22 @@ pub struct Snapshot { /// Output only. The time when the snapshot is created. #[prost(message, optional, tag = "4")] pub create_time: ::core::option::Option<::prost_types::Timestamp>, - /// Output only. The time when the snapshot will be deleted. The maximum amount - /// of time a snapshot can stay active is 365 days. If 'ttl' is not specified, + /// The time when the snapshot will be deleted. The maximum amount of time a + /// snapshot can stay active is 365 days. If 'ttl' is not specified, /// the default maximum of 365 days will be used. #[prost(message, optional, tag = "5")] pub delete_time: ::core::option::Option<::prost_types::Timestamp>, /// Output only. The current state of the snapshot. #[prost(enumeration = "snapshot::State", tag = "6")] pub state: i32, - /// Output only. Description of the snapshot. + /// Description of the snapshot. #[prost(string, tag = "7")] pub description: ::prost::alloc::string::String, } /// Nested message and enum types in `Snapshot`. pub mod snapshot { /// Possible states of a snapshot. + #[non_exhaustive] #[derive( Clone, Copy, @@ -520,13 +559,14 @@ pub mod snapshot { } } /// A backup of a Cloud Bigtable table. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Backup { /// A globally unique identifier for the backup which cannot be /// changed. Values are of the form /// `projects/{project}/instances/{instance}/clusters/{cluster}/ - /// backups/\[_a-zA-Z0-9][-_.a-zA-Z0-9\]*` + /// backups/[_a-zA-Z0-9][-_.a-zA-Z0-9]*` /// The final segment of the name must be between 1 and 50 characters /// in length. /// @@ -535,13 +575,18 @@ pub struct Backup { /// `projects/{project}/instances/{instance}/clusters/{cluster}`. #[prost(string, tag = "1")] pub name: ::prost::alloc::string::String, - /// Required. Immutable. Name of the table from which this backup was created. This needs - /// to be in the same instance as the backup. Values are of the form + /// Required. Immutable. Name of the table from which this backup was created. + /// This needs to be in the same instance as the backup. Values are of the form /// `projects/{project}/instances/{instance}/tables/{source_table}`. #[prost(string, tag = "2")] pub source_table: ::prost::alloc::string::String, + /// Output only. Name of the backup from which this backup was copied. If a + /// backup is not created by copying a backup, this field will be empty. Values + /// are of the form: projects//instances//backups/. + #[prost(string, tag = "10")] + pub source_backup: ::prost::alloc::string::String, /// Required. The expiration time of the backup, with microseconds - /// granularity that must be at least 6 hours and at most 30 days + /// granularity that must be at least 6 hours and at most 90 days /// from the time the request is received. Once the `expire_time` /// has passed, Cloud Bigtable will delete the backup and free the /// resources used by the backup. @@ -549,8 +594,9 @@ pub struct Backup { pub expire_time: ::core::option::Option<::prost_types::Timestamp>, /// Output only. `start_time` is the time that the backup was started /// (i.e. approximately the time the - /// \[CreateBackup][google.bigtable.admin.v2.BigtableTableAdmin.CreateBackup\] request is received). The - /// row data in this backup will be no older than this timestamp. + /// [CreateBackup][google.bigtable.admin.v2.BigtableTableAdmin.CreateBackup] + /// request is received). The row data in this backup will be no older than + /// this timestamp. #[prost(message, optional, tag = "4")] pub start_time: ::core::option::Option<::prost_types::Timestamp>, /// Output only. `end_time` is the time that the backup was finished. The row @@ -570,6 +616,7 @@ pub struct Backup { /// Nested message and enum types in `Backup`. pub mod backup { /// Indicates the current state of the backup. + #[non_exhaustive] #[derive( Clone, Copy, @@ -615,6 +662,7 @@ pub mod backup { } } /// Information about a backup. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct BackupInfo { @@ -632,8 +680,14 @@ pub struct BackupInfo { /// Output only. Name of the table the backup was created from. #[prost(string, tag = "4")] pub source_table: ::prost::alloc::string::String, + /// Output only. Name of the backup from which this backup was copied. If a + /// backup is not created by copying a backup, this field will be empty. Values + /// are of the form: projects//instances//backups/. + #[prost(string, tag = "10")] + pub source_backup: ::prost::alloc::string::String, } /// Indicates the type of the restore source. +#[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum RestoreSourceType { @@ -663,13 +717,13 @@ impl RestoreSourceType { } } /// The request for -/// \[RestoreTable][google.bigtable.admin.v2.BigtableTableAdmin.RestoreTable\]. +/// [RestoreTable][google.bigtable.admin.v2.BigtableTableAdmin.RestoreTable]. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RestoreTableRequest { /// Required. The name of the instance in which to create the restored - /// table. This instance must be in the same project as the source backup. - /// Values are of the form `projects//instances/`. + /// table. Values are of the form `projects//instances/`. #[prost(string, tag = "1")] pub parent: ::prost::alloc::string::String, /// Required. The id of the table to create and restore to. This @@ -685,6 +739,7 @@ pub struct RestoreTableRequest { /// Nested message and enum types in `RestoreTableRequest`. pub mod restore_table_request { /// Required. The source from which to restore. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Source { @@ -695,7 +750,8 @@ pub mod restore_table_request { } } /// Metadata type for the long-running operation returned by -/// \[RestoreTable][google.bigtable.admin.v2.BigtableTableAdmin.RestoreTable\]. +/// [RestoreTable][google.bigtable.admin.v2.BigtableTableAdmin.RestoreTable]. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RestoreTableMetadata { @@ -708,27 +764,31 @@ pub struct RestoreTableMetadata { /// If exists, the name of the long-running operation that will be used to /// track the post-restore optimization process to optimize the performance of /// the restored table. The metadata type of the long-running operation is - /// \[OptimizeRestoreTableMetadata][\]. The response type is - /// \[Empty][google.protobuf.Empty\]. This long-running operation may be + /// [OptimizeRestoreTableMetadata][]. The response type is + /// [Empty][google.protobuf.Empty]. This long-running operation may be /// automatically created by the system if applicable after the /// RestoreTable long-running operation completes successfully. This operation /// may not be created if the table is already optimized or the restore was /// not successful. #[prost(string, tag = "4")] pub optimize_table_operation_name: ::prost::alloc::string::String, - /// The progress of the \[RestoreTable][google.bigtable.admin.v2.BigtableTableAdmin.RestoreTable\] + /// The progress of the + /// [RestoreTable][google.bigtable.admin.v2.BigtableTableAdmin.RestoreTable] /// operation. #[prost(message, optional, tag = "5")] pub progress: ::core::option::Option, /// Information about the source used to restore the table, as specified by - /// `source` in \[RestoreTableRequest][google.bigtable.admin.v2.RestoreTableRequest\]. + /// `source` in + /// [RestoreTableRequest][google.bigtable.admin.v2.RestoreTableRequest]. #[prost(oneof = "restore_table_metadata::SourceInfo", tags = "3")] pub source_info: ::core::option::Option, } /// Nested message and enum types in `RestoreTableMetadata`. pub mod restore_table_metadata { /// Information about the source used to restore the table, as specified by - /// `source` in \[RestoreTableRequest][google.bigtable.admin.v2.RestoreTableRequest\]. + /// `source` in + /// [RestoreTableRequest][google.bigtable.admin.v2.RestoreTableRequest]. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum SourceInfo { @@ -740,6 +800,7 @@ pub mod restore_table_metadata { /// of optimizations performed on a newly restored table. This long-running /// operation is automatically created by the system after the successful /// completion of a table restore, and cannot be cancelled. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct OptimizeRestoredTableMetadata { @@ -751,7 +812,8 @@ pub struct OptimizeRestoredTableMetadata { pub progress: ::core::option::Option, } /// Request message for -/// \[google.bigtable.admin.v2.BigtableTableAdmin.CreateTable][google.bigtable.admin.v2.BigtableTableAdmin.CreateTable\] +/// [google.bigtable.admin.v2.BigtableTableAdmin.CreateTable][google.bigtable.admin.v2.BigtableTableAdmin.CreateTable] +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CreateTableRequest { @@ -759,8 +821,8 @@ pub struct CreateTableRequest { /// Values are of the form `projects/{project}/instances/{instance}`. #[prost(string, tag = "1")] pub parent: ::prost::alloc::string::String, - /// Required. The name by which the new table should be referred to within the parent - /// instance, e.g., `foobar` rather than `{parent}/tables/foobar`. + /// Required. The name by which the new table should be referred to within the + /// parent instance, e.g., `foobar` rather than `{parent}/tables/foobar`. /// Maximum 50 characters. #[prost(string, tag = "2")] pub table_id: ::prost::alloc::string::String, @@ -776,7 +838,7 @@ pub struct CreateTableRequest { /// /// * Row keys := `["a", "apple", "custom", "customer_1", "customer_2",` /// `"other", "zz"]` - /// * initial_split_keys := `["apple", "customer_1", "customer_2", "other"]` + /// * initial_split_keys := `\["apple", "customer_1", "customer_2", "other"\]` /// * Key assignment: /// - Tablet 1 `[, apple) => {"a"}.` /// - Tablet 2 `[apple, customer_1) => {"apple", "custom"}.` @@ -789,6 +851,7 @@ pub struct CreateTableRequest { /// Nested message and enum types in `CreateTableRequest`. pub mod create_table_request { /// An initial split point for a newly created table. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Split { @@ -798,12 +861,13 @@ pub mod create_table_request { } } /// Request message for -/// \[google.bigtable.admin.v2.BigtableTableAdmin.CreateTableFromSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.CreateTableFromSnapshot\] +/// [google.bigtable.admin.v2.BigtableTableAdmin.CreateTableFromSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.CreateTableFromSnapshot] /// /// Note: This is a private alpha release of Cloud Bigtable snapshots. This /// feature is not currently available to most Cloud Bigtable customers. This /// feature might be changed in backward-incompatible ways and is not recommended /// for production use. It is not subject to any SLA or deprecation policy. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CreateTableFromSnapshotRequest { @@ -811,19 +875,20 @@ pub struct CreateTableFromSnapshotRequest { /// Values are of the form `projects/{project}/instances/{instance}`. #[prost(string, tag = "1")] pub parent: ::prost::alloc::string::String, - /// Required. The name by which the new table should be referred to within the parent - /// instance, e.g., `foobar` rather than `{parent}/tables/foobar`. + /// Required. The name by which the new table should be referred to within the + /// parent instance, e.g., `foobar` rather than `{parent}/tables/foobar`. #[prost(string, tag = "2")] pub table_id: ::prost::alloc::string::String, - /// Required. The unique name of the snapshot from which to restore the table. The - /// snapshot and the table must be in the same instance. - /// Values are of the form + /// Required. The unique name of the snapshot from which to restore the table. + /// The snapshot and the table must be in the same instance. Values are of the + /// form /// `projects/{project}/instances/{instance}/clusters/{cluster}/snapshots/{snapshot}`. #[prost(string, tag = "3")] pub source_snapshot: ::prost::alloc::string::String, } /// Request message for -/// \[google.bigtable.admin.v2.BigtableTableAdmin.DropRowRange][google.bigtable.admin.v2.BigtableTableAdmin.DropRowRange\] +/// [google.bigtable.admin.v2.BigtableTableAdmin.DropRowRange][google.bigtable.admin.v2.BigtableTableAdmin.DropRowRange] +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DropRowRangeRequest { @@ -839,6 +904,7 @@ pub struct DropRowRangeRequest { /// Nested message and enum types in `DropRowRangeRequest`. pub mod drop_row_range_request { /// Delete all rows or by prefix. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Target { @@ -852,16 +918,17 @@ pub mod drop_row_range_request { } } /// Request message for -/// \[google.bigtable.admin.v2.BigtableTableAdmin.ListTables][google.bigtable.admin.v2.BigtableTableAdmin.ListTables\] +/// [google.bigtable.admin.v2.BigtableTableAdmin.ListTables][google.bigtable.admin.v2.BigtableTableAdmin.ListTables] +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListTablesRequest { - /// Required. The unique name of the instance for which tables should be listed. - /// Values are of the form `projects/{project}/instances/{instance}`. + /// Required. The unique name of the instance for which tables should be + /// listed. Values are of the form `projects/{project}/instances/{instance}`. #[prost(string, tag = "1")] pub parent: ::prost::alloc::string::String, /// The view to be applied to the returned tables' fields. - /// Only NAME_ONLY view (default) and REPLICATION_VIEW are supported. + /// NAME_ONLY view (default) and REPLICATION_VIEW are supported. #[prost(enumeration = "table::View", tag = "2")] pub view: i32, /// Maximum number of results per page. @@ -880,7 +947,8 @@ pub struct ListTablesRequest { pub page_token: ::prost::alloc::string::String, } /// Response message for -/// \[google.bigtable.admin.v2.BigtableTableAdmin.ListTables][google.bigtable.admin.v2.BigtableTableAdmin.ListTables\] +/// [google.bigtable.admin.v2.BigtableTableAdmin.ListTables][google.bigtable.admin.v2.BigtableTableAdmin.ListTables] +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListTablesResponse { @@ -894,7 +962,8 @@ pub struct ListTablesResponse { pub next_page_token: ::prost::alloc::string::String, } /// Request message for -/// \[google.bigtable.admin.v2.BigtableTableAdmin.GetTable][google.bigtable.admin.v2.BigtableTableAdmin.GetTable\] +/// [google.bigtable.admin.v2.BigtableTableAdmin.GetTable][google.bigtable.admin.v2.BigtableTableAdmin.GetTable] +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetTableRequest { @@ -909,7 +978,8 @@ pub struct GetTableRequest { pub view: i32, } /// The request for -/// \[UpdateTable][google.bigtable.admin.v2.BigtableTableAdmin.UpdateTable\]. +/// [UpdateTable][google.bigtable.admin.v2.BigtableTableAdmin.UpdateTable]. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct UpdateTableRequest { @@ -918,18 +988,23 @@ pub struct UpdateTableRequest { #[prost(message, optional, tag = "1")] pub table: ::core::option::Option, /// Required. The list of fields to update. - /// A mask specifying which fields (e.g. `deletion_protection`) in the `table` + /// A mask specifying which fields (e.g. `change_stream_config`) in the `table` /// field should be updated. This mask is relative to the `table` field, not to /// the request message. The wildcard (*) path is currently not supported. - /// Currently UpdateTable is only supported for the following field: - /// * `deletion_protection` + /// Currently UpdateTable is only supported for the following fields: + /// + /// * `change_stream_config` + /// * `change_stream_config.retention_period` + /// * `deletion_protection` + /// /// If `column_families` is set in `update_mask`, it will return an /// UNIMPLEMENTED error. #[prost(message, optional, tag = "2")] pub update_mask: ::core::option::Option<::prost_types::FieldMask>, } /// Metadata type for the operation returned by -/// \[UpdateTable][google.bigtable.admin.v2.BigtableTableAdmin.UpdateTable\]. +/// [UpdateTable][google.bigtable.admin.v2.BigtableTableAdmin.UpdateTable]. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct UpdateTableMetadata { @@ -944,7 +1019,8 @@ pub struct UpdateTableMetadata { pub end_time: ::core::option::Option<::prost_types::Timestamp>, } /// Request message for -/// \[google.bigtable.admin.v2.BigtableTableAdmin.DeleteTable][google.bigtable.admin.v2.BigtableTableAdmin.DeleteTable\] +/// [google.bigtable.admin.v2.BigtableTableAdmin.DeleteTable][google.bigtable.admin.v2.BigtableTableAdmin.DeleteTable] +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DeleteTableRequest { @@ -955,7 +1031,8 @@ pub struct DeleteTableRequest { pub name: ::prost::alloc::string::String, } /// Request message for -/// \[google.bigtable.admin.v2.BigtableTableAdmin.UndeleteTable][google.bigtable.admin.v2.BigtableTableAdmin.UndeleteTable\] +/// [google.bigtable.admin.v2.BigtableTableAdmin.UndeleteTable][google.bigtable.admin.v2.BigtableTableAdmin.UndeleteTable] +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct UndeleteTableRequest { @@ -966,7 +1043,8 @@ pub struct UndeleteTableRequest { pub name: ::prost::alloc::string::String, } /// Metadata type for the operation returned by -/// \[google.bigtable.admin.v2.BigtableTableAdmin.UndeleteTable][google.bigtable.admin.v2.BigtableTableAdmin.UndeleteTable\]. +/// [google.bigtable.admin.v2.BigtableTableAdmin.UndeleteTable][google.bigtable.admin.v2.BigtableTableAdmin.UndeleteTable]. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct UndeleteTableMetadata { @@ -981,7 +1059,8 @@ pub struct UndeleteTableMetadata { pub end_time: ::core::option::Option<::prost_types::Timestamp>, } /// Request message for -/// \[google.bigtable.admin.v2.BigtableTableAdmin.ModifyColumnFamilies][google.bigtable.admin.v2.BigtableTableAdmin.ModifyColumnFamilies\] +/// [google.bigtable.admin.v2.BigtableTableAdmin.ModifyColumnFamilies][google.bigtable.admin.v2.BigtableTableAdmin.ModifyColumnFamilies] +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ModifyColumnFamiliesRequest { @@ -990,10 +1069,10 @@ pub struct ModifyColumnFamiliesRequest { /// `projects/{project}/instances/{instance}/tables/{table}`. #[prost(string, tag = "1")] pub name: ::prost::alloc::string::String, - /// Required. Modifications to be atomically applied to the specified table's families. - /// Entries are applied in order, meaning that earlier modifications can be - /// masked by later ones (in the case of repeated updates to the same family, - /// for example). + /// Required. Modifications to be atomically applied to the specified table's + /// families. Entries are applied in order, meaning that earlier modifications + /// can be masked by later ones (in the case of repeated updates to the same + /// family, for example). #[prost(message, repeated, tag = "2")] pub modifications: ::prost::alloc::vec::Vec< modify_column_families_request::Modification, @@ -1002,6 +1081,7 @@ pub struct ModifyColumnFamiliesRequest { /// Nested message and enum types in `ModifyColumnFamiliesRequest`. pub mod modify_column_families_request { /// A create, update, or delete of a particular column family. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Modification { @@ -1015,6 +1095,7 @@ pub mod modify_column_families_request { /// Nested message and enum types in `Modification`. pub mod modification { /// Column family modifications. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Mod { @@ -1034,18 +1115,20 @@ pub mod modify_column_families_request { } } /// Request message for -/// \[google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken][google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken\] +/// [google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken][google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken] +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GenerateConsistencyTokenRequest { - /// Required. The unique name of the Table for which to create a consistency token. - /// Values are of the form + /// Required. The unique name of the Table for which to create a consistency + /// token. Values are of the form /// `projects/{project}/instances/{instance}/tables/{table}`. #[prost(string, tag = "1")] pub name: ::prost::alloc::string::String, } /// Response message for -/// \[google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken][google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken\] +/// [google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken][google.bigtable.admin.v2.BigtableTableAdmin.GenerateConsistencyToken] +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GenerateConsistencyTokenResponse { @@ -1054,12 +1137,13 @@ pub struct GenerateConsistencyTokenResponse { pub consistency_token: ::prost::alloc::string::String, } /// Request message for -/// \[google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency][google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency\] +/// [google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency][google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency] +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CheckConsistencyRequest { - /// Required. The unique name of the Table for which to check replication consistency. - /// Values are of the form + /// Required. The unique name of the Table for which to check replication + /// consistency. Values are of the form /// `projects/{project}/instances/{instance}/tables/{table}`. #[prost(string, tag = "1")] pub name: ::prost::alloc::string::String, @@ -1068,7 +1152,8 @@ pub struct CheckConsistencyRequest { pub consistency_token: ::prost::alloc::string::String, } /// Response message for -/// \[google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency][google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency\] +/// [google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency][google.bigtable.admin.v2.BigtableTableAdmin.CheckConsistency] +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CheckConsistencyResponse { @@ -1078,12 +1163,13 @@ pub struct CheckConsistencyResponse { pub consistent: bool, } /// Request message for -/// \[google.bigtable.admin.v2.BigtableTableAdmin.SnapshotTable][google.bigtable.admin.v2.BigtableTableAdmin.SnapshotTable\] +/// [google.bigtable.admin.v2.BigtableTableAdmin.SnapshotTable][google.bigtable.admin.v2.BigtableTableAdmin.SnapshotTable] /// /// Note: This is a private alpha release of Cloud Bigtable snapshots. This /// feature is not currently available to most Cloud Bigtable customers. This /// feature might be changed in backward-incompatible ways and is not recommended /// for production use. It is not subject to any SLA or deprecation policy. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SnapshotTableRequest { @@ -1097,9 +1183,9 @@ pub struct SnapshotTableRequest { /// `projects/{project}/instances/{instance}/clusters/{cluster}`. #[prost(string, tag = "2")] pub cluster: ::prost::alloc::string::String, - /// Required. The ID by which the new snapshot should be referred to within the parent - /// cluster, e.g., `mysnapshot` of the form: `\[_a-zA-Z0-9][-_.a-zA-Z0-9\]*` - /// rather than + /// Required. The ID by which the new snapshot should be referred to within the + /// parent cluster, e.g., `mysnapshot` of the form: + /// `[_a-zA-Z0-9][-_.a-zA-Z0-9]*` rather than /// `projects/{project}/instances/{instance}/clusters/{cluster}/snapshots/mysnapshot`. #[prost(string, tag = "3")] pub snapshot_id: ::prost::alloc::string::String, @@ -1114,12 +1200,13 @@ pub struct SnapshotTableRequest { pub description: ::prost::alloc::string::String, } /// Request message for -/// \[google.bigtable.admin.v2.BigtableTableAdmin.GetSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.GetSnapshot\] +/// [google.bigtable.admin.v2.BigtableTableAdmin.GetSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.GetSnapshot] /// /// Note: This is a private alpha release of Cloud Bigtable snapshots. This /// feature is not currently available to most Cloud Bigtable customers. This /// feature might be changed in backward-incompatible ways and is not recommended /// for production use. It is not subject to any SLA or deprecation policy. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetSnapshotRequest { @@ -1130,17 +1217,18 @@ pub struct GetSnapshotRequest { pub name: ::prost::alloc::string::String, } /// Request message for -/// \[google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots][google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots\] +/// [google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots][google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots] /// /// Note: This is a private alpha release of Cloud Bigtable snapshots. This /// feature is not currently available to most Cloud Bigtable customers. This /// feature might be changed in backward-incompatible ways and is not recommended /// for production use. It is not subject to any SLA or deprecation policy. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListSnapshotsRequest { - /// Required. The unique name of the cluster for which snapshots should be listed. - /// Values are of the form + /// Required. The unique name of the cluster for which snapshots should be + /// listed. Values are of the form /// `projects/{project}/instances/{instance}/clusters/{cluster}`. /// Use `{cluster} = '-'` to list snapshots for all clusters in an instance, /// e.g., `projects/{project}/instances/{instance}/clusters/-`. @@ -1155,12 +1243,13 @@ pub struct ListSnapshotsRequest { pub page_token: ::prost::alloc::string::String, } /// Response message for -/// \[google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots][google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots\] +/// [google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots][google.bigtable.admin.v2.BigtableTableAdmin.ListSnapshots] /// /// Note: This is a private alpha release of Cloud Bigtable snapshots. This /// feature is not currently available to most Cloud Bigtable customers. This /// feature might be changed in backward-incompatible ways and is not recommended /// for production use. It is not subject to any SLA or deprecation policy. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListSnapshotsResponse { @@ -1174,12 +1263,13 @@ pub struct ListSnapshotsResponse { pub next_page_token: ::prost::alloc::string::String, } /// Request message for -/// \[google.bigtable.admin.v2.BigtableTableAdmin.DeleteSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.DeleteSnapshot\] +/// [google.bigtable.admin.v2.BigtableTableAdmin.DeleteSnapshot][google.bigtable.admin.v2.BigtableTableAdmin.DeleteSnapshot] /// /// Note: This is a private alpha release of Cloud Bigtable snapshots. This /// feature is not currently available to most Cloud Bigtable customers. This /// feature might be changed in backward-incompatible ways and is not recommended /// for production use. It is not subject to any SLA or deprecation policy. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DeleteSnapshotRequest { @@ -1195,6 +1285,7 @@ pub struct DeleteSnapshotRequest { /// feature is not currently available to most Cloud Bigtable customers. This /// feature might be changed in backward-incompatible ways and is not recommended /// for production use. It is not subject to any SLA or deprecation policy. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SnapshotTableMetadata { @@ -1214,6 +1305,7 @@ pub struct SnapshotTableMetadata { /// feature is not currently available to most Cloud Bigtable customers. This /// feature might be changed in backward-incompatible ways and is not recommended /// for production use. It is not subject to any SLA or deprecation policy. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CreateTableFromSnapshotMetadata { @@ -1228,7 +1320,9 @@ pub struct CreateTableFromSnapshotMetadata { #[prost(message, optional, tag = "3")] pub finish_time: ::core::option::Option<::prost_types::Timestamp>, } -/// The request for \[CreateBackup][google.bigtable.admin.v2.BigtableTableAdmin.CreateBackup\]. +/// The request for +/// [CreateBackup][google.bigtable.admin.v2.BigtableTableAdmin.CreateBackup]. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CreateBackupRequest { @@ -1242,7 +1336,7 @@ pub struct CreateBackupRequest { /// the full backup name, of the form: /// `projects/{project}/instances/{instance}/clusters/{cluster}/backups/{backup_id}`. /// This string must be between 1 and 50 characters in length and match the - /// regex \[_a-zA-Z0-9][-_.a-zA-Z0-9\]*. + /// regex [_a-zA-Z0-9][-_.a-zA-Z0-9]*. #[prost(string, tag = "2")] pub backup_id: ::prost::alloc::string::String, /// Required. The backup to create. @@ -1250,7 +1344,8 @@ pub struct CreateBackupRequest { pub backup: ::core::option::Option, } /// Metadata type for the operation returned by -/// \[CreateBackup][google.bigtable.admin.v2.BigtableTableAdmin.CreateBackup\]. +/// [CreateBackup][google.bigtable.admin.v2.BigtableTableAdmin.CreateBackup]. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CreateBackupMetadata { @@ -1267,13 +1362,16 @@ pub struct CreateBackupMetadata { #[prost(message, optional, tag = "4")] pub end_time: ::core::option::Option<::prost_types::Timestamp>, } -/// The request for \[UpdateBackup][google.bigtable.admin.v2.BigtableTableAdmin.UpdateBackup\]. +/// The request for +/// [UpdateBackup][google.bigtable.admin.v2.BigtableTableAdmin.UpdateBackup]. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct UpdateBackupRequest { /// Required. The backup to update. `backup.name`, and the fields to be updated /// as specified by `update_mask` are required. Other fields are ignored. /// Update is only supported for the following fields: + /// /// * `backup.expire_time`. #[prost(message, optional, tag = "1")] pub backup: ::core::option::Option, @@ -1285,7 +1383,9 @@ pub struct UpdateBackupRequest { #[prost(message, optional, tag = "2")] pub update_mask: ::core::option::Option<::prost_types::FieldMask>, } -/// The request for \[GetBackup][google.bigtable.admin.v2.BigtableTableAdmin.GetBackup\]. +/// The request for +/// [GetBackup][google.bigtable.admin.v2.BigtableTableAdmin.GetBackup]. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetBackupRequest { @@ -1295,7 +1395,9 @@ pub struct GetBackupRequest { #[prost(string, tag = "1")] pub name: ::prost::alloc::string::String, } -/// The request for \[DeleteBackup][google.bigtable.admin.v2.BigtableTableAdmin.DeleteBackup\]. +/// The request for +/// [DeleteBackup][google.bigtable.admin.v2.BigtableTableAdmin.DeleteBackup]. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DeleteBackupRequest { @@ -1305,7 +1407,9 @@ pub struct DeleteBackupRequest { #[prost(string, tag = "1")] pub name: ::prost::alloc::string::String, } -/// The request for \[ListBackups][google.bigtable.admin.v2.BigtableTableAdmin.ListBackups\]. +/// The request for +/// [ListBackups][google.bigtable.admin.v2.BigtableTableAdmin.ListBackups]. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListBackupsRequest { @@ -1323,13 +1427,14 @@ pub struct ListBackupsRequest { /// roughly synonymous with equality. Filter rules are case insensitive. /// /// The fields eligible for filtering are: - /// * `name` - /// * `source_table` - /// * `state` - /// * `start_time` (and values are of the format YYYY-MM-DDTHH:MM:SSZ) - /// * `end_time` (and values are of the format YYYY-MM-DDTHH:MM:SSZ) - /// * `expire_time` (and values are of the format YYYY-MM-DDTHH:MM:SSZ) - /// * `size_bytes` + /// + /// * `name` + /// * `source_table` + /// * `state` + /// * `start_time` (and values are of the format YYYY-MM-DDTHH:MM:SSZ) + /// * `end_time` (and values are of the format YYYY-MM-DDTHH:MM:SSZ) + /// * `expire_time` (and values are of the format YYYY-MM-DDTHH:MM:SSZ) + /// * `size_bytes` /// /// To filter on multiple expressions, provide each separate expression within /// parentheses. By default, each expression is an AND expression. However, @@ -1337,30 +1442,32 @@ pub struct ListBackupsRequest { /// /// Some examples of using filters are: /// - /// * `name:"exact"` --> The backup's name is the string "exact". - /// * `name:howl` --> The backup's name contains the string "howl". - /// * `source_table:prod` - /// --> The source_table's name contains the string "prod". - /// * `state:CREATING` --> The backup is pending creation. - /// * `state:READY` --> The backup is fully created and ready for use. - /// * `(name:howl) AND (start_time < \"2018-03-28T14:50:00Z\")` - /// --> The backup name contains the string "howl" and start_time - /// of the backup is before 2018-03-28T14:50:00Z. - /// * `size_bytes > 10000000000` --> The backup's size is greater than 10GB + /// * `name:"exact"` --> The backup's name is the string "exact". + /// * `name:howl` --> The backup's name contains the string "howl". + /// * `source_table:prod` + /// --> The source_table's name contains the string "prod". + /// * `state:CREATING` --> The backup is pending creation. + /// * `state:READY` --> The backup is fully created and ready for use. + /// * `(name:howl) AND (start_time < \"2018-03-28T14:50:00Z\")` + /// --> The backup name contains the string "howl" and start_time + /// of the backup is before 2018-03-28T14:50:00Z. + /// * `size_bytes > 10000000000` --> The backup's size is greater than 10GB #[prost(string, tag = "2")] pub filter: ::prost::alloc::string::String, /// An expression for specifying the sort order of the results of the request. - /// The string value should specify one or more fields in \[Backup][google.bigtable.admin.v2.Backup\]. The full - /// syntax is described at + /// The string value should specify one or more fields in + /// [Backup][google.bigtable.admin.v2.Backup]. The full syntax is described at + /// /// /// Fields supported are: - /// * name - /// * source_table - /// * expire_time - /// * start_time - /// * end_time - /// * size_bytes - /// * state + /// + /// * name + /// * source_table + /// * expire_time + /// * start_time + /// * end_time + /// * size_bytes + /// * state /// /// For example, "start_time". The default sorting order is ascending. /// To specify descending order for the field, a suffix " desc" should @@ -1376,13 +1483,16 @@ pub struct ListBackupsRequest { #[prost(int32, tag = "4")] pub page_size: i32, /// If non-empty, `page_token` should contain a - /// \[next_page_token][google.bigtable.admin.v2.ListBackupsResponse.next_page_token\] from a - /// previous \[ListBackupsResponse][google.bigtable.admin.v2.ListBackupsResponse\] to the same `parent` and with the same - /// `filter`. + /// [next_page_token][google.bigtable.admin.v2.ListBackupsResponse.next_page_token] + /// from a previous + /// [ListBackupsResponse][google.bigtable.admin.v2.ListBackupsResponse] to the + /// same `parent` and with the same `filter`. #[prost(string, tag = "5")] pub page_token: ::prost::alloc::string::String, } -/// The response for \[ListBackups][google.bigtable.admin.v2.BigtableTableAdmin.ListBackups\]. +/// The response for +/// [ListBackups][google.bigtable.admin.v2.BigtableTableAdmin.ListBackups]. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListBackupsResponse { @@ -1390,11 +1500,67 @@ pub struct ListBackupsResponse { #[prost(message, repeated, tag = "1")] pub backups: ::prost::alloc::vec::Vec, /// `next_page_token` can be sent in a subsequent - /// \[ListBackups][google.bigtable.admin.v2.BigtableTableAdmin.ListBackups\] call to fetch more - /// of the matching backups. + /// [ListBackups][google.bigtable.admin.v2.BigtableTableAdmin.ListBackups] call + /// to fetch more of the matching backups. #[prost(string, tag = "2")] pub next_page_token: ::prost::alloc::string::String, } +/// The request for +/// [CopyBackup][google.bigtable.admin.v2.BigtableTableAdmin.CopyBackup]. +#[non_exhaustive] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CopyBackupRequest { + /// Required. The name of the destination cluster that will contain the backup + /// copy. The cluster must already exists. Values are of the form: + /// `projects/{project}/instances/{instance}/clusters/{cluster}`. + #[prost(string, tag = "1")] + pub parent: ::prost::alloc::string::String, + /// Required. The id of the new backup. The `backup_id` along with `parent` + /// are combined as {parent}/backups/{backup_id} to create the full backup + /// name, of the form: + /// `projects/{project}/instances/{instance}/clusters/{cluster}/backups/{backup_id}`. + /// This string must be between 1 and 50 characters in length and match the + /// regex [_a-zA-Z0-9][-_.a-zA-Z0-9]*. + #[prost(string, tag = "2")] + pub backup_id: ::prost::alloc::string::String, + /// Required. The source backup to be copied from. + /// The source backup needs to be in READY state for it to be copied. + /// Copying a copied backup is not allowed. + /// Once CopyBackup is in progress, the source backup cannot be deleted or + /// cleaned up on expiration until CopyBackup is finished. + /// Values are of the form: + /// `projects//instances//clusters//backups/`. + #[prost(string, tag = "3")] + pub source_backup: ::prost::alloc::string::String, + /// Required. Required. The expiration time of the copied backup with + /// microsecond granularity that must be at least 6 hours and at most 30 days + /// from the time the request is received. Once the `expire_time` has + /// passed, Cloud Bigtable will delete the backup and free the resources used + /// by the backup. + #[prost(message, optional, tag = "4")] + pub expire_time: ::core::option::Option<::prost_types::Timestamp>, +} +/// Metadata type for the google.longrunning.Operation returned by +/// [CopyBackup][google.bigtable.admin.v2.BigtableTableAdmin.CopyBackup]. +#[non_exhaustive] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CopyBackupMetadata { + /// The name of the backup being created through the copy operation. + /// Values are of the form + /// `projects//instances//clusters//backups/`. + #[prost(string, tag = "1")] + pub name: ::prost::alloc::string::String, + /// Information about the source backup that is being copied from. + #[prost(message, optional, tag = "2")] + pub source_backup_info: ::core::option::Option, + /// The progress of the + /// [CopyBackup][google.bigtable.admin.v2.BigtableTableAdmin.CopyBackup] + /// operation. + #[prost(message, optional, tag = "3")] + pub progress: ::core::option::Option, +} /// Generated client implementations. pub mod bigtable_table_admin_client { #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] @@ -1979,8 +2145,8 @@ pub mod bigtable_table_admin_client { /// [metadata][google.longrunning.Operation.metadata] field type is /// [CreateBackupMetadata][google.bigtable.admin.v2.CreateBackupMetadata]. The /// [response][google.longrunning.Operation.response] field type is - /// [Backup][google.bigtable.admin.v2.Backup], if successful. Cancelling the returned operation will stop the - /// creation and delete the backup. + /// [Backup][google.bigtable.admin.v2.Backup], if successful. Cancelling the + /// returned operation will stop the creation and delete the backup. pub async fn create_backup( &mut self, request: impl tonic::IntoRequest, @@ -2127,8 +2293,7 @@ pub mod bigtable_table_admin_client { ); self.inner.unary(req, path, codec).await } - /// Create a new table by restoring from a completed backup. The new table - /// must be in the same project as the instance containing the backup. The + /// Create a new table by restoring from a completed backup. The /// returned table [long-running operation][google.longrunning.Operation] can /// be used to track the progress of the operation, and to cancel it. The /// [metadata][google.longrunning.Operation.metadata] field type is @@ -2165,6 +2330,38 @@ pub mod bigtable_table_admin_client { ); self.inner.unary(req, path, codec).await } + /// Copy a Cloud Bigtable backup to a new backup in the destination cluster + /// located in the destination instance and project. + pub async fn copy_backup( + &mut self, + request: impl tonic::IntoRequest, + ) -> std::result::Result< + tonic::Response, + tonic::Status, + > { + self.inner + .ready() + .await + .map_err(|e| { + tonic::Status::new( + tonic::Code::Unknown, + format!("Service was not ready: {}", e.into()), + ) + })?; + let codec = tonic::codec::ProstCodec::default(); + let path = http::uri::PathAndQuery::from_static( + "/google.bigtable.admin.v2.BigtableTableAdmin/CopyBackup", + ); + let mut req = request.into_request(); + req.extensions_mut() + .insert( + GrpcMethod::new( + "google.bigtable.admin.v2.BigtableTableAdmin", + "CopyBackup", + ), + ); + self.inner.unary(req, path, codec).await + } /// Gets the access control policy for a Table or Backup resource. /// Returns an empty policy if the resource exists but does not have a policy /// set. @@ -2234,7 +2431,8 @@ pub mod bigtable_table_admin_client { ); self.inner.unary(req, path, codec).await } - /// Returns permissions that the caller has on the specified Table or Backup resource. + /// Returns permissions that the caller has on the specified Table or Backup + /// resource. pub async fn test_iam_permissions( &mut self, request: impl tonic::IntoRequest< diff --git a/src/generated/google.bigtable.v2.rs b/src/generated/google.bigtable.v2.rs index e0e966a..c228efc 100644 --- a/src/generated/google.bigtable.v2.rs +++ b/src/generated/google.bigtable.v2.rs @@ -1,5 +1,6 @@ /// Specifies the complete (requested) contents of a single row of a table. /// Rows which exceed 256MiB in size cannot be read in full. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Row { @@ -15,6 +16,7 @@ pub struct Row { } /// Specifies (some of) the contents of a single row/column family intersection /// of a table. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Family { @@ -32,6 +34,7 @@ pub struct Family { } /// Specifies (some of) the contents of a single row/column intersection of a /// table. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Column { @@ -47,6 +50,7 @@ pub struct Column { pub cells: ::prost::alloc::vec::Vec, } /// Specifies (some of) the contents of a single row/column/timestamp of a table. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Cell { @@ -63,11 +67,12 @@ pub struct Cell { /// length. #[prost(bytes = "bytes", tag = "2")] pub value: ::prost::bytes::Bytes, - /// Labels applied to the cell by a \[RowFilter][google.bigtable.v2.RowFilter\]. + /// Labels applied to the cell by a [RowFilter][google.bigtable.v2.RowFilter]. #[prost(string, repeated, tag = "3")] pub labels: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, } /// Specifies a contiguous range of rows. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RowRange { @@ -84,6 +89,7 @@ pub struct RowRange { pub mod row_range { /// The row key at which to start the range. /// If neither field is set, interpreted as the empty string, inclusive. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum StartKey { @@ -96,6 +102,7 @@ pub mod row_range { } /// The row key at which to end the range. /// If neither field is set, interpreted as the infinite row key, exclusive. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum EndKey { @@ -108,6 +115,7 @@ pub mod row_range { } } /// Specifies a non-contiguous set of rows. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RowSet { @@ -122,6 +130,7 @@ pub struct RowSet { /// The range spans from <column_family>:<start_qualifier> to /// <column_family>:<end_qualifier>, where both bounds can be either /// inclusive or exclusive. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ColumnRange { @@ -141,6 +150,7 @@ pub struct ColumnRange { pub mod column_range { /// The column qualifier at which to start the range (within `column_family`). /// If neither field is set, interpreted as the empty string, inclusive. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum StartQualifier { @@ -153,6 +163,7 @@ pub mod column_range { } /// The column qualifier at which to end the range (within `column_family`). /// If neither field is set, interpreted as the infinite string, exclusive. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum EndQualifier { @@ -165,6 +176,7 @@ pub mod column_range { } } /// Specified a contiguous range of microsecond timestamps. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TimestampRange { @@ -176,6 +188,7 @@ pub struct TimestampRange { pub end_timestamp_micros: i64, } /// Specifies a contiguous range of raw byte values. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ValueRange { @@ -192,6 +205,7 @@ pub struct ValueRange { pub mod value_range { /// The value at which to start the range. /// If neither field is set, interpreted as the empty string, inclusive. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum StartValue { @@ -204,6 +218,7 @@ pub mod value_range { } /// The value at which to end the range. /// If neither field is set, interpreted as the infinite string, exclusive. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum EndValue { @@ -248,6 +263,7 @@ pub mod value_range { /// The total serialized size of a RowFilter message must not /// exceed 20480 bytes, and RowFilters may not be nested within each other /// (in Chains or Interleaves) to a depth of more than 20. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RowFilter { @@ -262,6 +278,7 @@ pub struct RowFilter { /// Nested message and enum types in `RowFilter`. pub mod row_filter { /// A RowFilter which sends rows through several RowFilters in sequence. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Chain { @@ -273,10 +290,37 @@ pub mod row_filter { } /// A RowFilter which sends each row to each of several component /// RowFilters and interleaves the results. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Interleave { + /// The elements of "filters" all process a copy of the input row, and the + /// results are pooled, sorted, and combined into a single output row. + /// If multiple cells are produced with the same column and timestamp, + /// they will all appear in the output row in an unspecified mutual order. + /// Consider the following example, with three filters: + /// + /// input row + /// | + /// ----------------------------------------------------- + /// | | | + /// f(0) f(1) f(2) + /// | | | + /// 1: foo,bar,10,x foo,bar,10,z far,bar,7,a + /// 2: foo,blah,11,z far,blah,5,x far,blah,5,x + /// | | | + /// ----------------------------------------------------- + /// | + /// 1: foo,bar,10,z // could have switched with #2 + /// 2: foo,bar,10,x // could have switched with #1 + /// 3: foo,blah,11,z + /// 4: far,bar,7,a + /// 5: far,blah,5,x // identical to #6 + /// 6: far,blah,5,x // identical to #5 + /// + /// All interleaved filters are executed atomically. #[prost(message, repeated, tag = "1")] + #[cfg(not(doctest))] pub filters: ::prost::alloc::vec::Vec, } /// A RowFilter which evaluates one of two possible RowFilters, depending on @@ -286,6 +330,7 @@ pub mod row_filter { /// true and false filters, which may lead to inconsistent or unexpected /// results. Additionally, Condition filters have poor performance, especially /// when filters are set for the false condition. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Condition { @@ -311,6 +356,7 @@ pub mod row_filter { } /// Which of the possible RowFilter types to apply. If none are set, this /// RowFilter returns all cells in the input row. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Filter { @@ -420,6 +466,7 @@ pub mod row_filter { } } /// Specifies a particular change to be made to the contents of a row. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Mutation { @@ -430,6 +477,7 @@ pub struct Mutation { /// Nested message and enum types in `Mutation`. pub mod mutation { /// A Mutation which sets the value of the specified cell. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SetCell { @@ -454,6 +502,7 @@ pub mod mutation { } /// A Mutation which deletes cells from the specified column, optionally /// restricting the deletions to a given timestamp range. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DeleteFromColumn { @@ -470,6 +519,7 @@ pub mod mutation { pub time_range: ::core::option::Option, } /// A Mutation which deletes all cells from the specified column family. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DeleteFromFamily { @@ -479,10 +529,12 @@ pub mod mutation { pub family_name: ::prost::alloc::string::String, } /// A Mutation which deletes all cells from the containing row. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DeleteFromRow {} /// Which of the possible Mutation types to apply. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Mutation { @@ -502,6 +554,7 @@ pub mod mutation { } /// Specifies an atomic read/modify/write operation on the latest value of the /// specified column. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ReadModifyWriteRule { @@ -523,6 +576,7 @@ pub struct ReadModifyWriteRule { pub mod read_modify_write_rule { /// The rule used to determine the column's new latest value from its current /// latest value. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Rule { @@ -541,6 +595,7 @@ pub mod read_modify_write_rule { } /// NOTE: This API is intended to be used by Apache Beam BigtableIO. /// A partition of a change stream. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct StreamPartition { @@ -552,6 +607,7 @@ pub struct StreamPartition { /// NOTE: This API is intended to be used by Apache Beam BigtableIO. /// The information required to continue reading the data from multiple /// `StreamPartitions` from where a previous read left off. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct StreamContinuationTokens { @@ -562,6 +618,7 @@ pub struct StreamContinuationTokens { /// NOTE: This API is intended to be used by Apache Beam BigtableIO. /// The information required to continue reading the data from a /// `StreamPartition` from where a previous read left off. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct StreamContinuationToken { @@ -575,6 +632,7 @@ pub struct StreamContinuationToken { /// ReadIterationStats captures information about the iteration of rows or cells /// over the course of a read, e.g. how many results were scanned in a read /// operation versus the results returned. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ReadIterationStats { @@ -596,6 +654,7 @@ pub struct ReadIterationStats { /// RequestLatencyStats provides a measurement of the latency of the request as /// it interacts with different systems over its lifetime, e.g. how long the /// request took to execute within a frontend server. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RequestLatencyStats { @@ -620,6 +679,7 @@ pub struct RequestLatencyStats { pub frontend_server_latency: ::core::option::Option<::prost_types::Duration>, } /// FullReadStatsView captures all known information about a read. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct FullReadStatsView { @@ -638,6 +698,7 @@ pub struct FullReadStatsView { /// single request, helpful for evaluating the performance of the sent request. /// Currently, there are the following supported methods: /// * google.bigtable.v2.ReadRows +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RequestStats { @@ -654,6 +715,7 @@ pub mod request_stats { /// based on the requested view. /// /// See the messages above for additional context. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum StatsView { @@ -664,6 +726,7 @@ pub mod request_stats { } } /// Request message for Bigtable.ReadRows. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ReadRowsRequest { @@ -672,8 +735,8 @@ pub struct ReadRowsRequest { /// `projects//instances//tables/
`. #[prost(string, tag = "1")] pub table_name: ::prost::alloc::string::String, - /// This value specifies routing for replication. This API only accepts the - /// empty value of app_profile_id. + /// This value specifies routing for replication. If not specified, the + /// "default" application profile will be used. #[prost(string, tag = "5")] pub app_profile_id: ::prost::alloc::string::String, /// The row keys and/or ranges to read sequentially. If not specified, reads @@ -691,13 +754,28 @@ pub struct ReadRowsRequest { /// The view into RequestStats, as described above. #[prost(enumeration = "read_rows_request::RequestStatsView", tag = "6")] pub request_stats_view: i32, + /// Experimental API - Please note that this API is currently experimental + /// and can change in the future. + /// + /// Return rows in lexiographical descending order of the row keys. The row + /// contents will not be affected by this flag. + /// + /// Example result set: + /// + /// [ + /// {key: "k2", "f:col1": "v1", "f:col2": "v1"}, + /// {key: "k1", "f:col1": "v2", "f:col2": "v2"} + /// ] + #[prost(bool, tag = "7")] + #[cfg(not(doctest))] + pub reversed: bool, } /// Nested message and enum types in `ReadRowsRequest`. pub mod read_rows_request { - /// /// The desired view into RequestStats that should be returned in the response. /// /// See also: RequestStats message. + #[non_exhaustive] #[derive( Clone, Copy, @@ -744,6 +822,7 @@ pub mod read_rows_request { } } /// Response message for Bigtable.ReadRows. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ReadRowsResponse { @@ -771,12 +850,12 @@ pub struct ReadRowsResponse { /// chunks and request_stats filled. /// /// Visually, response messages will stream as follows: - /// ... -> {chunks: \[...\]} -> {chunks: [], request_stats: {...}} + /// ... -> {chunks: \[...\]} -> {chunks: \[\], request_stats: {...}} /// \______________________/ \________________________________/ /// Primary response Trailer of RequestStats info /// /// Or if the read did not return any values: - /// {chunks: [], request_stats: {...}} + /// {chunks: \[\], request_stats: {...}} /// \________________________________/ /// Trailer of RequestStats info #[prost(message, optional, tag = "3")] @@ -786,6 +865,7 @@ pub struct ReadRowsResponse { pub mod read_rows_response { /// Specifies a piece of a row's contents returned as part of the read /// response stream. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CellChunk { @@ -821,7 +901,7 @@ pub mod read_rows_response { #[prost(int64, tag = "4")] pub timestamp_micros: i64, /// Labels applied to the cell by a - /// \[RowFilter][google.bigtable.v2.RowFilter\]. Labels are only set + /// [RowFilter][google.bigtable.v2.RowFilter]. Labels are only set /// on the first CellChunk per cell. #[prost(string, repeated, tag = "5")] pub labels: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, @@ -845,6 +925,7 @@ pub mod read_rows_response { /// Nested message and enum types in `CellChunk`. pub mod cell_chunk { /// Signals to the client concerning previous CellChunks received. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum RowStatus { @@ -860,6 +941,7 @@ pub mod read_rows_response { } } /// Request message for Bigtable.SampleRowKeys. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SampleRowKeysRequest { @@ -874,6 +956,7 @@ pub struct SampleRowKeysRequest { pub app_profile_id: ::prost::alloc::string::String, } /// Response message for Bigtable.SampleRowKeys. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SampleRowKeysResponse { @@ -894,6 +977,7 @@ pub struct SampleRowKeysResponse { pub offset_bytes: i64, } /// Request message for Bigtable.MutateRow. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MutateRowRequest { @@ -916,10 +1000,12 @@ pub struct MutateRowRequest { pub mutations: ::prost::alloc::vec::Vec, } /// Response message for Bigtable.MutateRow. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MutateRowResponse {} /// Request message for BigtableService.MutateRows. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MutateRowsRequest { @@ -942,6 +1028,7 @@ pub struct MutateRowsRequest { /// Nested message and enum types in `MutateRowsRequest`. pub mod mutate_rows_request { /// A mutation for a given row. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Entry { @@ -956,16 +1043,23 @@ pub mod mutate_rows_request { } } /// Response message for BigtableService.MutateRows. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MutateRowsResponse { /// One or more results for Entries from the batch request. #[prost(message, repeated, tag = "1")] pub entries: ::prost::alloc::vec::Vec, + /// Information about how client should limit the rate (QPS). Primirily used by + /// supported official Cloud Bigtable clients. If unset, the rate limit info is + /// not provided by the server. + #[prost(message, optional, tag = "3")] + pub rate_limit_info: ::core::option::Option, } /// Nested message and enum types in `MutateRowsResponse`. pub mod mutate_rows_response { /// The result of applying a passed mutation in the original request. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Entry { @@ -981,7 +1075,33 @@ pub mod mutate_rows_response { pub status: ::core::option::Option, } } +/// Information about how client should adjust the load to Bigtable. +#[non_exhaustive] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct RateLimitInfo { + /// Time that clients should wait before adjusting the target rate again. + /// If clients adjust rate too frequently, the impact of the previous + /// adjustment may not have been taken into account and may + /// over-throttle or under-throttle. If clients adjust rate too slowly, they + /// will not be responsive to load changes on server side, and may + /// over-throttle or under-throttle. + #[prost(message, optional, tag = "1")] + pub period: ::core::option::Option<::prost_types::Duration>, + /// If it has been at least one `period` since the last load adjustment, the + /// client should multiply the current load by this value to get the new target + /// load. For example, if the current load is 100 and `factor` is 0.8, the new + /// target load should be 80. After adjusting, the client should ignore + /// `factor` until another `period` has passed. + /// + /// The client can measure its load using any unit that's comparable over time + /// For example, QPS can be used as long as each request involves a similar + /// amount of work. + #[prost(double, tag = "2")] + pub factor: f64, +} /// Request message for Bigtable.CheckAndMutateRow. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CheckAndMutateRowRequest { @@ -1020,6 +1140,7 @@ pub struct CheckAndMutateRowRequest { pub false_mutations: ::prost::alloc::vec::Vec, } /// Response message for Bigtable.CheckAndMutateRow. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CheckAndMutateRowResponse { @@ -1029,6 +1150,7 @@ pub struct CheckAndMutateRowResponse { pub predicate_matched: bool, } /// Request message for client connection keep-alive and warming. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PingAndWarmRequest { @@ -1043,10 +1165,12 @@ pub struct PingAndWarmRequest { pub app_profile_id: ::prost::alloc::string::String, } /// Response message for Bigtable.PingAndWarm connection keepalive and warming. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PingAndWarmResponse {} /// Request message for Bigtable.ReadModifyWriteRow. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ReadModifyWriteRowRequest { @@ -1070,6 +1194,7 @@ pub struct ReadModifyWriteRowRequest { pub rules: ::prost::alloc::vec::Vec, } /// Response message for Bigtable.ReadModifyWriteRow. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ReadModifyWriteRowResponse { @@ -1079,6 +1204,7 @@ pub struct ReadModifyWriteRowResponse { } /// NOTE: This API is intended to be used by Apache Beam BigtableIO. /// Request message for Bigtable.GenerateInitialChangeStreamPartitions. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GenerateInitialChangeStreamPartitionsRequest { @@ -1096,6 +1222,7 @@ pub struct GenerateInitialChangeStreamPartitionsRequest { } /// NOTE: This API is intended to be used by Apache Beam BigtableIO. /// Response message for Bigtable.GenerateInitialChangeStreamPartitions. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GenerateInitialChangeStreamPartitionsResponse { @@ -1105,6 +1232,7 @@ pub struct GenerateInitialChangeStreamPartitionsResponse { } /// NOTE: This API is intended to be used by Apache Beam BigtableIO. /// Request message for Bigtable.ReadChangeStream. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ReadChangeStreamRequest { @@ -1138,6 +1266,7 @@ pub struct ReadChangeStreamRequest { /// Nested message and enum types in `ReadChangeStreamRequest`. pub mod read_change_stream_request { /// Options for describing where we want to start reading from the stream. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum StartFrom { @@ -1163,6 +1292,7 @@ pub mod read_change_stream_request { } /// NOTE: This API is intended to be used by Apache Beam BigtableIO. /// Response message for Bigtable.ReadChangeStream. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ReadChangeStreamResponse { @@ -1173,6 +1303,7 @@ pub struct ReadChangeStreamResponse { /// Nested message and enum types in `ReadChangeStreamResponse`. pub mod read_change_stream_response { /// A partial or complete mutation. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MutationChunk { @@ -1191,6 +1322,7 @@ pub mod read_change_stream_response { /// Information about the chunking of this mutation. /// Only `SetCell` mutations can be chunked, and all chunks for a `SetCell` /// will be delivered contiguously with no other mutation types interleaved. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ChunkInfo { @@ -1212,6 +1344,7 @@ pub mod read_change_stream_response { /// the first in a sequence will only have the `type` and `chunks` fields /// populated, with the final message in the sequence also containing `done` /// set to true. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DataChange { @@ -1264,6 +1397,7 @@ pub mod read_change_stream_response { /// Nested message and enum types in `DataChange`. pub mod data_change { /// The type of mutation. + #[non_exhaustive] #[derive( Clone, Copy, @@ -1314,6 +1448,7 @@ pub mod read_change_stream_response { } /// A periodic message with information that can be used to checkpoint /// the state of a stream. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Heartbeat { @@ -1350,6 +1485,7 @@ pub mod read_change_stream_response { /// To read the new partition [A,C), supply the continuation tokens whose /// ranges cover the new partition, for example ContinuationToken[A,B) & /// ContinuationToken[B,C). + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CloseStream { @@ -1369,6 +1505,7 @@ pub mod read_change_stream_response { pub new_partitions: ::prost::alloc::vec::Vec, } /// The data or control message on the stream. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum StreamRecord { diff --git a/src/generated/google.iam.v1.rs b/src/generated/google.iam.v1.rs index fe9c524..c1ab902 100644 --- a/src/generated/google.iam.v1.rs +++ b/src/generated/google.iam.v1.rs @@ -1,4 +1,5 @@ /// Encapsulates settings provided to GetIamPolicy. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetPolicyOptions { @@ -23,6 +24,7 @@ pub struct GetPolicyOptions { #[prost(int32, tag = "1")] pub requested_policy_version: i32, } +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Policy { @@ -84,6 +86,7 @@ pub struct Policy { pub etag: ::prost::bytes::Bytes, } /// Associates `members`, or principals, with a `role`. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Binding { @@ -91,7 +94,7 @@ pub struct Binding { /// For example, `roles/viewer`, `roles/editor`, or `roles/owner`. #[prost(string, tag = "1")] pub role: ::prost::alloc::string::String, - /// Specifies the principals requesting access for a Cloud Platform resource. + /// Specifies the principals requesting access for a Google Cloud resource. /// `members` can have the following values: /// /// * `allUsers`: A special identifier that represents anyone who is @@ -152,6 +155,7 @@ pub struct Binding { #[prost(message, optional, tag = "3")] pub condition: ::core::option::Option, } +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct AuditConfig { @@ -164,6 +168,7 @@ pub struct AuditConfig { #[prost(message, repeated, tag = "3")] pub audit_log_configs: ::prost::alloc::vec::Vec, } +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct AuditLogConfig { @@ -173,7 +178,7 @@ pub struct AuditLogConfig { /// Specifies the identities that do not cause logging for this type of /// permission. /// Follows the same format of - /// \[Binding.members][google.iam.v1.Binding.members\]. + /// [Binding.members][google.iam.v1.Binding.members]. #[prost(string, repeated, tag = "2")] pub exempted_members: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, } @@ -181,6 +186,7 @@ pub struct AuditLogConfig { pub mod audit_log_config { /// The list of valid permission types for which logging can be configured. /// Admin writes are always logged, and are not configurable. + #[non_exhaustive] #[derive( Clone, Copy, @@ -229,6 +235,7 @@ pub mod audit_log_config { } } /// The difference delta between two policies. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PolicyDelta { @@ -241,6 +248,7 @@ pub struct PolicyDelta { } /// One delta entry for Binding. Each individual change (only one member in each /// entry) to a binding will be a separate entry. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct BindingDelta { @@ -253,7 +261,7 @@ pub struct BindingDelta { /// Required #[prost(string, tag = "2")] pub role: ::prost::alloc::string::String, - /// A single identity requesting access for a Cloud Platform resource. + /// A single identity requesting access for a Google Cloud resource. /// Follows the same format of Binding.members. /// Required #[prost(string, tag = "3")] @@ -265,6 +273,7 @@ pub struct BindingDelta { /// Nested message and enum types in `BindingDelta`. pub mod binding_delta { /// The type of action performed on a Binding in a policy. + #[non_exhaustive] #[derive( Clone, Copy, @@ -310,6 +319,7 @@ pub mod binding_delta { } /// One delta entry for AuditConfig. Each individual change (only one /// exempted_member in each entry) to a AuditConfig will be a separate entry. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct AuditConfigDelta { @@ -337,6 +347,7 @@ pub struct AuditConfigDelta { /// Nested message and enum types in `AuditConfigDelta`. pub mod audit_config_delta { /// The type of action performed on an audit configuration in a policy. + #[non_exhaustive] #[derive( Clone, Copy, @@ -381,6 +392,7 @@ pub mod audit_config_delta { } } /// Request message for `SetIamPolicy` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SetIamPolicyRequest { @@ -403,6 +415,7 @@ pub struct SetIamPolicyRequest { pub update_mask: ::core::option::Option<::prost_types::FieldMask>, } /// Request message for `GetIamPolicy` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetIamPolicyRequest { @@ -416,6 +429,7 @@ pub struct GetIamPolicyRequest { pub options: ::core::option::Option, } /// Request message for `TestIamPermissions` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TestIamPermissionsRequest { @@ -431,6 +445,7 @@ pub struct TestIamPermissionsRequest { pub permissions: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, } /// Response message for `TestIamPermissions` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TestIamPermissionsResponse { diff --git a/src/generated/google.longrunning.rs b/src/generated/google.longrunning.rs index b4552a5..cd10e2a 100644 --- a/src/generated/google.longrunning.rs +++ b/src/generated/google.longrunning.rs @@ -1,5 +1,6 @@ /// This resource represents a long-running operation that is the result of a /// network API call. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Operation { @@ -30,6 +31,7 @@ pub mod operation { /// The operation result, which can be either an `error` or a valid `response`. /// If `done` == `false`, neither `error` nor `response` is set. /// If `done` == `true`, exactly one of `error` or `response` is set. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Result { @@ -48,7 +50,8 @@ pub mod operation { Response(::prost_types::Any), } } -/// The request message for \[Operations.GetOperation][google.longrunning.Operations.GetOperation\]. +/// The request message for [Operations.GetOperation][google.longrunning.Operations.GetOperation]. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetOperationRequest { @@ -56,7 +59,8 @@ pub struct GetOperationRequest { #[prost(string, tag = "1")] pub name: ::prost::alloc::string::String, } -/// The request message for \[Operations.ListOperations][google.longrunning.Operations.ListOperations\]. +/// The request message for [Operations.ListOperations][google.longrunning.Operations.ListOperations]. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListOperationsRequest { @@ -73,7 +77,8 @@ pub struct ListOperationsRequest { #[prost(string, tag = "3")] pub page_token: ::prost::alloc::string::String, } -/// The response message for \[Operations.ListOperations][google.longrunning.Operations.ListOperations\]. +/// The response message for [Operations.ListOperations][google.longrunning.Operations.ListOperations]. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListOperationsResponse { @@ -84,7 +89,8 @@ pub struct ListOperationsResponse { #[prost(string, tag = "2")] pub next_page_token: ::prost::alloc::string::String, } -/// The request message for \[Operations.CancelOperation][google.longrunning.Operations.CancelOperation\]. +/// The request message for [Operations.CancelOperation][google.longrunning.Operations.CancelOperation]. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CancelOperationRequest { @@ -92,7 +98,8 @@ pub struct CancelOperationRequest { #[prost(string, tag = "1")] pub name: ::prost::alloc::string::String, } -/// The request message for \[Operations.DeleteOperation][google.longrunning.Operations.DeleteOperation\]. +/// The request message for [Operations.DeleteOperation][google.longrunning.Operations.DeleteOperation]. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DeleteOperationRequest { @@ -100,7 +107,8 @@ pub struct DeleteOperationRequest { #[prost(string, tag = "1")] pub name: ::prost::alloc::string::String, } -/// The request message for \[Operations.WaitOperation][google.longrunning.Operations.WaitOperation\]. +/// The request message for [Operations.WaitOperation][google.longrunning.Operations.WaitOperation]. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct WaitOperationRequest { @@ -124,6 +132,7 @@ pub struct WaitOperationRequest { /// metadata_type: "LongRunningRecognizeMetadata" /// }; /// } +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct OperationInfo { diff --git a/src/generated/google.pubsub.v1.rs b/src/generated/google.pubsub.v1.rs index ea32645..109e8f5 100644 --- a/src/generated/google.pubsub.v1.rs +++ b/src/generated/google.pubsub.v1.rs @@ -1,4 +1,5 @@ /// A schema resource. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Schema { @@ -24,6 +25,7 @@ pub struct Schema { /// Nested message and enum types in `Schema`. pub mod schema { /// Possible schema definition types. + #[non_exhaustive] #[derive( Clone, Copy, @@ -68,6 +70,7 @@ pub mod schema { } } /// Request for the CreateSchema method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CreateSchemaRequest { @@ -91,6 +94,7 @@ pub struct CreateSchemaRequest { pub schema_id: ::prost::alloc::string::String, } /// Request for the GetSchema method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetSchemaRequest { @@ -104,6 +108,7 @@ pub struct GetSchemaRequest { pub view: i32, } /// Request for the `ListSchemas` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListSchemasRequest { @@ -126,6 +131,7 @@ pub struct ListSchemasRequest { pub page_token: ::prost::alloc::string::String, } /// Response for the `ListSchemas` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListSchemasResponse { @@ -138,6 +144,7 @@ pub struct ListSchemasResponse { pub next_page_token: ::prost::alloc::string::String, } /// Request for the `ListSchemaRevisions` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListSchemaRevisionsRequest { @@ -158,6 +165,7 @@ pub struct ListSchemaRevisionsRequest { pub page_token: ::prost::alloc::string::String, } /// Response for the `ListSchemaRevisions` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListSchemaRevisionsResponse { @@ -170,6 +178,7 @@ pub struct ListSchemaRevisionsResponse { pub next_page_token: ::prost::alloc::string::String, } /// Request for CommitSchema method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CommitSchemaRequest { @@ -182,6 +191,7 @@ pub struct CommitSchemaRequest { pub schema: ::core::option::Option, } /// Request for the `RollbackSchema` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RollbackSchemaRequest { @@ -196,6 +206,7 @@ pub struct RollbackSchemaRequest { pub revision_id: ::prost::alloc::string::String, } /// Request for the `DeleteSchemaRevision` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DeleteSchemaRevisionRequest { @@ -213,6 +224,7 @@ pub struct DeleteSchemaRevisionRequest { pub revision_id: ::prost::alloc::string::String, } /// Request for the `DeleteSchema` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DeleteSchemaRequest { @@ -222,6 +234,7 @@ pub struct DeleteSchemaRequest { pub name: ::prost::alloc::string::String, } /// Request for the `ValidateSchema` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ValidateSchemaRequest { @@ -235,10 +248,12 @@ pub struct ValidateSchemaRequest { } /// Response for the `ValidateSchema` method. /// Empty for now. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ValidateSchemaResponse {} /// Request for the `ValidateMessage` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ValidateMessageRequest { @@ -257,6 +272,7 @@ pub struct ValidateMessageRequest { } /// Nested message and enum types in `ValidateMessageRequest`. pub mod validate_message_request { + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum SchemaSpec { @@ -272,10 +288,12 @@ pub mod validate_message_request { } /// Response for the `ValidateMessage` method. /// Empty for now. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ValidateMessageResponse {} /// View of Schema object fields to be returned by GetSchema and ListSchemas. +#[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum SchemaView { @@ -310,6 +328,7 @@ impl SchemaView { } } /// Possible encoding types for messages. +#[non_exhaustive] #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] pub enum Encoding { @@ -698,20 +717,23 @@ pub mod schema_service_client { } } /// A policy constraining the storage of messages published to the topic. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct MessageStoragePolicy { - /// A list of IDs of GCP regions where messages that are published to the topic - /// may be persisted in storage. Messages published by publishers running in - /// non-allowed GCP regions (or running outside of GCP altogether) will be - /// routed for storage in one of the allowed regions. An empty list means that - /// no regions are allowed, and is not a valid configuration. + /// A list of IDs of Google Cloud regions where messages that are published + /// to the topic may be persisted in storage. Messages published by publishers + /// running in non-allowed Google Cloud regions (or running outside of Google + /// Cloud altogether) are routed for storage in one of the allowed regions. + /// An empty list means that no regions are allowed, and is not a valid + /// configuration. #[prost(string, repeated, tag = "1")] pub allowed_persistence_regions: ::prost::alloc::vec::Vec< ::prost::alloc::string::String, >, } /// Settings for validating messages published against a schema. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SchemaSettings { @@ -736,6 +758,7 @@ pub struct SchemaSettings { pub last_revision_id: ::prost::alloc::string::String, } /// A topic resource. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Topic { @@ -747,7 +770,7 @@ pub struct Topic { /// must not start with `"goog"`. #[prost(string, tag = "1")] pub name: ::prost::alloc::string::String, - /// See [Creating and managing labels] + /// See \[Creating and managing labels\] /// (). #[prost(map = "string, string", tag = "2")] pub labels: ::std::collections::HashMap< @@ -788,9 +811,10 @@ pub struct Topic { /// Note that client libraries represent this object differently /// depending on the language. See the corresponding [client library /// documentation]() for -/// more information. See [quotas and limits] +/// more information. See \[quotas and limits\] /// () for more information about message /// limits. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PubsubMessage { @@ -829,6 +853,7 @@ pub struct PubsubMessage { pub ordering_key: ::prost::alloc::string::String, } /// Request for the GetTopic method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetTopicRequest { @@ -838,6 +863,7 @@ pub struct GetTopicRequest { pub topic: ::prost::alloc::string::String, } /// Request for the UpdateTopic method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct UpdateTopicRequest { @@ -853,6 +879,7 @@ pub struct UpdateTopicRequest { pub update_mask: ::core::option::Option<::prost_types::FieldMask>, } /// Request for the Publish method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PublishRequest { @@ -865,6 +892,7 @@ pub struct PublishRequest { pub messages: ::prost::alloc::vec::Vec, } /// Response for the `Publish` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PublishResponse { @@ -875,6 +903,7 @@ pub struct PublishResponse { pub message_ids: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, } /// Request for the `ListTopics` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListTopicsRequest { @@ -892,6 +921,7 @@ pub struct ListTopicsRequest { pub page_token: ::prost::alloc::string::String, } /// Response for the `ListTopics` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListTopicsResponse { @@ -904,6 +934,7 @@ pub struct ListTopicsResponse { pub next_page_token: ::prost::alloc::string::String, } /// Request for the `ListTopicSubscriptions` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListTopicSubscriptionsRequest { @@ -921,6 +952,7 @@ pub struct ListTopicSubscriptionsRequest { pub page_token: ::prost::alloc::string::String, } /// Response for the `ListTopicSubscriptions` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListTopicSubscriptionsResponse { @@ -934,6 +966,7 @@ pub struct ListTopicSubscriptionsResponse { pub next_page_token: ::prost::alloc::string::String, } /// Request for the `ListTopicSnapshots` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListTopicSnapshotsRequest { @@ -951,6 +984,7 @@ pub struct ListTopicSnapshotsRequest { pub page_token: ::prost::alloc::string::String, } /// Response for the `ListTopicSnapshots` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListTopicSnapshotsResponse { @@ -964,6 +998,7 @@ pub struct ListTopicSnapshotsResponse { pub next_page_token: ::prost::alloc::string::String, } /// Request for the `DeleteTopic` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DeleteTopicRequest { @@ -973,6 +1008,7 @@ pub struct DeleteTopicRequest { pub topic: ::prost::alloc::string::String, } /// Request for the DetachSubscription method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DetachSubscriptionRequest { @@ -983,12 +1019,14 @@ pub struct DetachSubscriptionRequest { } /// Response for the DetachSubscription method. /// Reserved for future use. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DetachSubscriptionResponse {} -/// A subscription resource. If none of `push_config` or `bigquery_config` is -/// set, then the subscriber will pull and ack messages using API methods. At -/// most one of these fields may be set. +/// A subscription resource. If none of `push_config`, `bigquery_config`, or +/// `cloud_storage_config` is set, then the subscriber will pull and ack messages +/// using API methods. At most one of these fields may be set. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Subscription { @@ -1013,6 +1051,10 @@ pub struct Subscription { /// used to configure it. #[prost(message, optional, tag = "18")] pub bigquery_config: ::core::option::Option, + /// If delivery to Google Cloud Storage is used with this subscription, this + /// field is used to configure it. + #[prost(message, optional, tag = "22")] + pub cloud_storage_config: ::core::option::Option, /// The approximate amount of time (on a best-effort basis) Pub/Sub waits for /// the subscriber to acknowledge receipt before resending the message. In the /// interval after the message is delivered and before it is acknowledged, it @@ -1038,7 +1080,7 @@ pub struct Subscription { /// Indicates whether to retain acknowledged messages. If true, then /// messages are not expunged from the subscription's backlog, even if they are /// acknowledged, until they fall out of the `message_retention_duration` - /// window. This must be true if you would like to [`Seek` to a timestamp] + /// window. This must be true if you would like to \[`Seek` to a timestamp\] /// () in /// the past to replay previously-acknowledged messages. #[prost(bool, tag = "7")] @@ -1137,6 +1179,7 @@ pub struct Subscription { /// Nested message and enum types in `Subscription`. pub mod subscription { /// Possible states for a subscription. + #[non_exhaustive] #[derive( Clone, Copy, @@ -1193,6 +1236,7 @@ pub mod subscription { /// Retry Policy is implemented on a best effort basis. At times, the delay /// between consecutive deliveries may not match the configuration. That is, /// delay can be more or less than configured backoff. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct RetryPolicy { @@ -1210,6 +1254,7 @@ pub struct RetryPolicy { /// /// If validation on any of the fields fails at subscription creation/updation, /// the create/update subscription request will fail. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DeadLetterPolicy { @@ -1242,6 +1287,7 @@ pub struct DeadLetterPolicy { } /// A policy that specifies the conditions for resource expiration (i.e., /// automatic resource deletion). +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ExpirationPolicy { @@ -1255,6 +1301,7 @@ pub struct ExpirationPolicy { pub ttl: ::core::option::Option<::prost_types::Duration>, } /// Configuration for a push delivery endpoint. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PushConfig { @@ -1295,20 +1342,25 @@ pub struct PushConfig { /// authenticated push. #[prost(oneof = "push_config::AuthenticationMethod", tags = "3")] pub authentication_method: ::core::option::Option, + /// The format of the delivered message to the push endpoint is defined by + /// the chosen wrapper. When unset, `PubsubWrapper` is used. + #[prost(oneof = "push_config::Wrapper", tags = "4, 5")] + pub wrapper: ::core::option::Option, } /// Nested message and enum types in `PushConfig`. pub mod push_config { /// Contains information needed for generating an /// [OpenID Connect /// token](). + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct OidcToken { /// [Service account /// email]() - /// to be used for generating the OIDC token. The caller (for - /// CreateSubscription, UpdateSubscription, and ModifyPushConfig RPCs) must - /// have the iam.serviceAccounts.actAs permission for the service account. + /// used for generating the OIDC token. For more information + /// on setting up authentication, see + /// [Push subscriptions](). #[prost(string, tag = "1")] pub service_account_email: ::prost::alloc::string::String, /// Audience to be used when generating OIDC token. The audience claim @@ -1320,11 +1372,30 @@ pub mod push_config { #[prost(string, tag = "2")] pub audience: ::prost::alloc::string::String, } + /// The payload to the push endpoint is in the form of the JSON representation + /// of a PubsubMessage + /// (). + #[non_exhaustive] + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct PubsubWrapper {} + /// Sets the `data` field as the HTTP body for delivery. + #[non_exhaustive] + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct NoWrapper { + /// When true, writes the Pub/Sub message metadata to + /// `x-goog-pubsub-:` headers of the HTTP request. Writes the + /// Pub/Sub message attributes to `:` headers of the HTTP request. + #[prost(bool, tag = "1")] + pub write_metadata: bool, + } /// An authentication method used by push endpoints to verify the source of /// push requests. This can be used with push endpoints that are private by /// default to allow requests only from the Cloud Pub/Sub system, for example. /// This field is optional and should be set only by users interested in /// authenticated push. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum AuthenticationMethod { @@ -1333,8 +1404,24 @@ pub mod push_config { #[prost(message, tag = "3")] OidcToken(OidcToken), } + /// The format of the delivered message to the push endpoint is defined by + /// the chosen wrapper. When unset, `PubsubWrapper` is used. + #[non_exhaustive] + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum Wrapper { + /// When set, the payload to the push endpoint is in the form of the JSON + /// representation of a PubsubMessage + /// (). + #[prost(message, tag = "4")] + PubsubWrapper(PubsubWrapper), + /// When set, the payload to the push endpoint is not wrapped. + #[prost(message, tag = "5")] + NoWrapper(NoWrapper), + } } /// Configuration for a BigQuery subscription. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct BigQueryConfig { @@ -1368,6 +1455,7 @@ pub struct BigQueryConfig { /// Nested message and enum types in `BigQueryConfig`. pub mod big_query_config { /// Possible states for a BigQuery subscription. + #[non_exhaustive] #[derive( Clone, Copy, @@ -1390,7 +1478,7 @@ pub mod big_query_config { /// - Pub/Sub SA has not been granted the [appropriate BigQuery IAM /// permissions]() /// - bigquery.googleapis.com API is not enabled for the project - /// (\[instructions\]()) + /// ([instructions]()) PermissionDenied = 2, /// Cannot write to the BigQuery table because it does not exist. NotFound = 3, @@ -1424,7 +1512,132 @@ pub mod big_query_config { } } } +/// Configuration for a Cloud Storage subscription. +#[non_exhaustive] +#[allow(clippy::derive_partial_eq_without_eq)] +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct CloudStorageConfig { + /// Required. User-provided name for the Cloud Storage bucket. + /// The bucket must be created by the user. The bucket name must be without + /// any prefix like "gs://". See the [bucket naming + /// requirements] (). + #[prost(string, tag = "1")] + pub bucket: ::prost::alloc::string::String, + /// User-provided prefix for Cloud Storage filename. See the [object naming + /// requirements](). + #[prost(string, tag = "2")] + pub filename_prefix: ::prost::alloc::string::String, + /// User-provided suffix for Cloud Storage filename. See the [object naming + /// requirements](). Must + /// not end in "/". + #[prost(string, tag = "3")] + pub filename_suffix: ::prost::alloc::string::String, + /// The maximum duration that can elapse before a new Cloud Storage file is + /// created. Min 1 minute, max 10 minutes, default 5 minutes. May not exceed + /// the subscription's acknowledgement deadline. + #[prost(message, optional, tag = "6")] + pub max_duration: ::core::option::Option<::prost_types::Duration>, + /// The maximum bytes that can be written to a Cloud Storage file before a new + /// file is created. Min 1 KB, max 10 GiB. The max_bytes limit may be exceeded + /// in cases where messages are larger than the limit. + #[prost(int64, tag = "7")] + pub max_bytes: i64, + /// Output only. An output-only field that indicates whether or not the + /// subscription can receive messages. + #[prost(enumeration = "cloud_storage_config::State", tag = "9")] + pub state: i32, + /// Defaults to text format. + #[prost(oneof = "cloud_storage_config::OutputFormat", tags = "4, 5")] + pub output_format: ::core::option::Option, +} +/// Nested message and enum types in `CloudStorageConfig`. +pub mod cloud_storage_config { + /// Configuration for writing message data in text format. + /// Message payloads will be written to files as raw text, separated by a + /// newline. + #[non_exhaustive] + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct TextConfig {} + /// Configuration for writing message data in Avro format. + /// Message payloads and metadata will be written to files as an Avro binary. + #[non_exhaustive] + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Message)] + pub struct AvroConfig { + /// When true, write the subscription name, message_id, publish_time, + /// attributes, and ordering_key as additional fields in the output. The + /// subscription name, message_id, and publish_time fields are put in their + /// own fields while all other message properties other than data (for + /// example, an ordering_key, if present) are added as entries in the + /// attributes map. + #[prost(bool, tag = "1")] + pub write_metadata: bool, + } + /// Possible states for a Cloud Storage subscription. + #[non_exhaustive] + #[derive( + Clone, + Copy, + Debug, + PartialEq, + Eq, + Hash, + PartialOrd, + Ord, + ::prost::Enumeration + )] + #[repr(i32)] + pub enum State { + /// Default value. This value is unused. + Unspecified = 0, + /// The subscription can actively send messages to Cloud Storage. + Active = 1, + /// Cannot write to the Cloud Storage bucket because of permission denied + /// errors. + PermissionDenied = 2, + /// Cannot write to the Cloud Storage bucket because it does not exist. + NotFound = 3, + } + impl State { + /// String value of the enum field names used in the ProtoBuf definition. + /// + /// The values are not transformed in any way and thus are considered stable + /// (if the ProtoBuf definition does not change) and safe for programmatic use. + pub fn as_str_name(&self) -> &'static str { + match self { + State::Unspecified => "STATE_UNSPECIFIED", + State::Active => "ACTIVE", + State::PermissionDenied => "PERMISSION_DENIED", + State::NotFound => "NOT_FOUND", + } + } + /// Creates an enum from field names used in the ProtoBuf definition. + pub fn from_str_name(value: &str) -> ::core::option::Option { + match value { + "STATE_UNSPECIFIED" => Some(Self::Unspecified), + "ACTIVE" => Some(Self::Active), + "PERMISSION_DENIED" => Some(Self::PermissionDenied), + "NOT_FOUND" => Some(Self::NotFound), + _ => None, + } + } + } + /// Defaults to text format. + #[non_exhaustive] + #[allow(clippy::derive_partial_eq_without_eq)] + #[derive(Clone, PartialEq, ::prost::Oneof)] + pub enum OutputFormat { + /// If set, message data will be written to Cloud Storage in text format. + #[prost(message, tag = "4")] + TextConfig(TextConfig), + /// If set, message data will be written to Cloud Storage in Avro format. + #[prost(message, tag = "5")] + AvroConfig(AvroConfig), + } +} /// A message and its corresponding acknowledgment ID. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ReceivedMessage { @@ -1454,6 +1667,7 @@ pub struct ReceivedMessage { pub delivery_attempt: i32, } /// Request for the GetSubscription method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetSubscriptionRequest { @@ -1463,6 +1677,7 @@ pub struct GetSubscriptionRequest { pub subscription: ::prost::alloc::string::String, } /// Request for the UpdateSubscription method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct UpdateSubscriptionRequest { @@ -1475,6 +1690,7 @@ pub struct UpdateSubscriptionRequest { pub update_mask: ::core::option::Option<::prost_types::FieldMask>, } /// Request for the `ListSubscriptions` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListSubscriptionsRequest { @@ -1492,6 +1708,7 @@ pub struct ListSubscriptionsRequest { pub page_token: ::prost::alloc::string::String, } /// Response for the `ListSubscriptions` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListSubscriptionsResponse { @@ -1505,6 +1722,7 @@ pub struct ListSubscriptionsResponse { pub next_page_token: ::prost::alloc::string::String, } /// Request for the DeleteSubscription method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DeleteSubscriptionRequest { @@ -1514,6 +1732,7 @@ pub struct DeleteSubscriptionRequest { pub subscription: ::prost::alloc::string::String, } /// Request for the ModifyPushConfig method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ModifyPushConfigRequest { @@ -1531,6 +1750,7 @@ pub struct ModifyPushConfigRequest { pub push_config: ::core::option::Option, } /// Request for the `Pull` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PullRequest { @@ -1555,6 +1775,7 @@ pub struct PullRequest { pub max_messages: i32, } /// Response for the `Pull` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PullResponse { @@ -1567,6 +1788,7 @@ pub struct PullResponse { pub received_messages: ::prost::alloc::vec::Vec, } /// Request for the ModifyAckDeadline method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ModifyAckDeadlineRequest { @@ -1589,6 +1811,7 @@ pub struct ModifyAckDeadlineRequest { pub ack_deadline_seconds: i32, } /// Request for the Acknowledge method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct AcknowledgeRequest { @@ -1605,6 +1828,7 @@ pub struct AcknowledgeRequest { /// Request for the `StreamingPull` streaming RPC method. This request is used to /// establish the initial stream as well as to stream acknowledgements and ack /// deadline modifications from the client to the server. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct StreamingPullRequest { @@ -1682,6 +1906,7 @@ pub struct StreamingPullRequest { } /// Response for the `StreamingPull` method. This response is used to stream /// messages from the server to the client. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct StreamingPullResponse { @@ -1710,6 +1935,7 @@ pub struct StreamingPullResponse { pub mod streaming_pull_response { /// Acknowledgement IDs sent in one or more previous requests to acknowledge a /// previously received message. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct AcknowledgeConfirmation { @@ -1731,6 +1957,7 @@ pub mod streaming_pull_response { } /// Acknowledgement IDs sent in one or more previous requests to modify the /// deadline for a specific message. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ModifyAckDeadlineConfirmation { @@ -1748,6 +1975,7 @@ pub mod streaming_pull_response { >, } /// Subscription properties sent as part of the response. + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SubscriptionProperties { @@ -1760,6 +1988,7 @@ pub mod streaming_pull_response { } } /// Request for the `CreateSnapshot` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct CreateSnapshotRequest { @@ -1767,8 +1996,8 @@ pub struct CreateSnapshotRequest { /// in the request, the server will assign a random name for this snapshot on /// the same project as the subscription. Note that for REST API requests, you /// must specify a name. See the [resource name - /// rules](). Format - /// is `projects/{project}/snapshots/{snap}`. + /// rules](). + /// Format is `projects/{project}/snapshots/{snap}`. #[prost(string, tag = "1")] pub name: ::prost::alloc::string::String, /// Required. The subscription whose backlog the snapshot retains. @@ -1791,6 +2020,7 @@ pub struct CreateSnapshotRequest { >, } /// Request for the UpdateSnapshot method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct UpdateSnapshotRequest { @@ -1803,10 +2033,11 @@ pub struct UpdateSnapshotRequest { pub update_mask: ::core::option::Option<::prost_types::FieldMask>, } /// A snapshot resource. Snapshots are used in -/// \[Seek\]() +/// [Seek]() /// operations, which allow you to manage message acknowledgments in bulk. That /// is, you can set the acknowledgment state of messages in an existing /// subscription to the state captured by a snapshot. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Snapshot { @@ -1828,7 +2059,7 @@ pub struct Snapshot { /// snapshot that would expire in less than 1 hour after creation. #[prost(message, optional, tag = "3")] pub expire_time: ::core::option::Option<::prost_types::Timestamp>, - /// See [Creating and managing labels] + /// See \[Creating and managing labels\] /// (). #[prost(map = "string, string", tag = "4")] pub labels: ::std::collections::HashMap< @@ -1837,6 +2068,7 @@ pub struct Snapshot { >, } /// Request for the GetSnapshot method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct GetSnapshotRequest { @@ -1846,6 +2078,7 @@ pub struct GetSnapshotRequest { pub snapshot: ::prost::alloc::string::String, } /// Request for the `ListSnapshots` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListSnapshotsRequest { @@ -1863,6 +2096,7 @@ pub struct ListSnapshotsRequest { pub page_token: ::prost::alloc::string::String, } /// Response for the `ListSnapshots` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct ListSnapshotsResponse { @@ -1875,6 +2109,7 @@ pub struct ListSnapshotsResponse { pub next_page_token: ::prost::alloc::string::String, } /// Request for the `DeleteSnapshot` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct DeleteSnapshotRequest { @@ -1884,6 +2119,7 @@ pub struct DeleteSnapshotRequest { pub snapshot: ::prost::alloc::string::String, } /// Request for the `Seek` method. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SeekRequest { @@ -1895,6 +2131,7 @@ pub struct SeekRequest { } /// Nested message and enum types in `SeekRequest`. pub mod seek_request { + #[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Target { @@ -1919,6 +2156,7 @@ pub mod seek_request { } } /// Response for the `Seek` method (this response is empty). +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct SeekResponse {} @@ -2010,7 +2248,7 @@ pub mod publisher_client { self } /// Creates the given topic with the given name. See the [resource name rules] - /// (https://cloud.google.com/pubsub/docs/admin#resource_names). + /// (https://cloud.google.com/pubsub/docs/pubsub-basics#resource_names). pub async fn create_topic( &mut self, request: impl tonic::IntoRequest, @@ -2345,16 +2583,16 @@ pub mod subscriber_client { self } /// Creates a subscription to a given topic. See the [resource name rules] - /// (https://cloud.google.com/pubsub/docs/admin#resource_names). + /// (https://cloud.google.com/pubsub/docs/pubsub-basics#resource_names). /// If the subscription already exists, returns `ALREADY_EXISTS`. /// If the corresponding topic doesn't exist, returns `NOT_FOUND`. /// /// If the name is not provided in the request, the server will assign a random /// name for this subscription on the same project as the topic, conforming /// to the [resource name format] - /// (https://cloud.google.com/pubsub/docs/admin#resource_names). The generated - /// name is populated in the returned Subscription object. Note that for REST - /// API requests, you must specify a name in the request. + /// (https://cloud.google.com/pubsub/docs/pubsub-basics#resource_names). The + /// generated name is populated in the returned Subscription object. Note that + /// for REST API requests, you must specify a name in the request. pub async fn create_subscription( &mut self, request: impl tonic::IntoRequest, @@ -2702,7 +2940,7 @@ pub mod subscriber_client { /// the request, the server will assign a random /// name for this snapshot on the same project as the subscription, conforming /// to the [resource name format] - /// (https://cloud.google.com/pubsub/docs/admin#resource_names). The + /// (https://cloud.google.com/pubsub/docs/pubsub-basics#resource_names). The /// generated name is populated in the returned Snapshot object. Note that for /// REST API requests, you must specify a name in the request. pub async fn create_snapshot( diff --git a/src/generated/google.r#type.rs b/src/generated/google.r#type.rs index 45d8c50..ed4b1d7 100644 --- a/src/generated/google.r#type.rs +++ b/src/generated/google.r#type.rs @@ -1,3 +1,35 @@ +/// Represents a textual expression in the Common Expression Language (CEL) +/// syntax. CEL is a C-like expression language. The syntax and semantics of CEL +/// are documented at +/// +/// Example (Comparison): +/// +/// title: "Summary size limit" +/// description: "Determines if a summary is less than 100 chars" +/// expression: "document.summary.size() < 100" +/// +/// Example (Equality): +/// +/// title: "Requestor is owner" +/// description: "Determines if requestor is the document owner" +/// expression: "document.owner == request.auth.claims.email" +/// +/// Example (Logic): +/// +/// title: "Public documents" +/// description: "Determine whether the document should be publicly visible" +/// expression: "document.type != 'private' && document.type != 'internal'" +/// +/// Example (Data Manipulation): +/// +/// title: "Notification string" +/// description: "Create a notification string with a timestamp." +/// expression: "'New message received at ' + string(document.create_time)" +/// +/// The exact variables and functions that may be referenced within an expression +/// are determined by the service that evaluates it. See the service +/// documentation for additional information. +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Expr { diff --git a/src/generated/google.rpc.rs b/src/generated/google.rpc.rs index e20cb14..8293f99 100644 --- a/src/generated/google.rpc.rs +++ b/src/generated/google.rpc.rs @@ -1,20 +1,21 @@ /// The `Status` type defines a logical error model that is suitable for /// different programming environments, including REST APIs and RPC APIs. It is -/// used by \[gRPC\](). Each `Status` message contains +/// used by [gRPC](). Each `Status` message contains /// three pieces of data: error code, error message, and error details. /// /// You can find out more about this error model and how to work with it in the /// [API Design Guide](). +#[non_exhaustive] #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Status { /// The status code, which should be an enum value of - /// \[google.rpc.Code][google.rpc.Code\]. + /// [google.rpc.Code][google.rpc.Code]. #[prost(int32, tag = "1")] pub code: i32, /// A developer-facing error message, which should be in English. Any /// user-facing error message should be localized and sent in the - /// \[google.rpc.Status.details][google.rpc.Status.details\] field, or localized + /// [google.rpc.Status.details][google.rpc.Status.details] field, or localized /// by the client. #[prost(string, tag = "2")] pub message: ::prost::alloc::string::String, diff --git a/src/grpc/mod.rs b/src/grpc/mod.rs index 0f6fbac..ea6c84c 100644 --- a/src/grpc/mod.rs +++ b/src/grpc/mod.rs @@ -1,4 +1,13 @@ //! Items and functionality specific to gRPC services +pub use tonic::{ + body::BoxBody, + client::GrpcService, + codegen::{Body, Bytes, StdError}, +}; + mod status_code_set; pub use status_code_set::StatusCodeSet; + +/// The default grpc transport implementation +pub type DefaultGrpcImpl = crate::auth::grpc::AuthGrpcService; diff --git a/src/lib.rs b/src/lib.rs index 50bc0c8..f71035b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,12 +18,6 @@ " )] -// re-export the Connect trait because users will need it for the bound on clients -pub use ::hyper::client::connect::Connect; - -// a convenience alias -pub(crate) type Auth = yup_oauth2::authenticator::Authenticator; - /// Make a given config struct into a builder using the given default values for fields macro_rules! config_default { ( @@ -42,6 +36,7 @@ macro_rules! config_default { } ) => { $(#[$struct_attr])* + #[non_exhaustive] $struct_vis struct $struct_name { $( $(#[$field_attr])* @@ -125,8 +120,7 @@ pub mod storage; mod builder; pub use builder::{ - AuthFlow, ClientBuilder, ClientBuilderConfig, CreateBuilderError, DefaultConnector, - ServiceAccountAuth, + AuthFlow, ClientBuilder, ClientBuilderConfig, CreateBuilderError, ServiceAccountAuth, }; pub mod retry_policy; diff --git a/src/pubsub/client_builder.rs b/src/pubsub/client_builder.rs index 57bc4aa..adca62d 100644 --- a/src/pubsub/client_builder.rs +++ b/src/pubsub/client_builder.rs @@ -1,6 +1,5 @@ use crate::{ - auth::grpc, - builder, + builder, grpc, pubsub::{api, PublisherClient, SubscriberClient}, }; @@ -17,7 +16,6 @@ pub use tower::make::MakeConnection; config_default! { /// Configuration for connecting to pubsub #[derive(Debug, Clone, Eq, PartialEq, Hash, serde::Deserialize)] - #[non_exhaustive] pub struct PubSubConfig { /// Endpoint to connect to pubsub over. @default("https://pubsub.googleapis.com/v1".into(), "PubSubConfig::default_endpoint") @@ -34,28 +32,16 @@ config_default! { #[error(transparent)] pub struct BuildError(#[from] tonic::transport::Error); -impl builder::ClientBuilder -where - C: tower::Service + Clone + Send + Sync + 'static, - C::Response: hyper::client::connect::Connection - + tokio::io::AsyncRead - + tokio::io::AsyncWrite - + Send - + Unpin - + 'static, - C::Future: Send + Unpin + 'static, - C::Error: Into>, - Box: From, -{ +impl builder::ClientBuilder { async fn pubsub_authed_service( &self, config: PubSubConfig, - ) -> Result, BuildError> { + ) -> Result { let connection = tonic::transport::Endpoint::new(config.endpoint)? - .connect_with_connector(self.connector.clone()) + .connect() .await?; - Ok(grpc::AuthGrpcService::new( + Ok(grpc::DefaultGrpcImpl::new( connection, self.auth.clone(), config.auth_scopes, @@ -66,28 +52,26 @@ where pub async fn build_pubsub_publisher( &self, config: PubSubConfig, - ) -> Result, BuildError> { + ) -> Result { // the crate's client will wrap the raw grpc client to add features/functions/ergonomics - Ok(PublisherClient { - inner: api::publisher_client::PublisherClient::new( - self.pubsub_authed_service(config).await?, - ) - .max_decoding_message_size(MAX_MESSAGE_SIZE), - }) + Ok(PublisherClient::from_raw_api( + api::publisher_client::PublisherClient::new(self.pubsub_authed_service(config).await?) + .max_decoding_message_size(MAX_MESSAGE_SIZE), + )) } /// Create a client for subscribing to the pubsub service pub async fn build_pubsub_subscriber( &self, config: PubSubConfig, - ) -> Result, BuildError> { + ) -> Result { // the crate's client will wrap the raw grpc client to add features/functions/ergonomics - Ok(SubscriberClient { - inner: api::subscriber_client::SubscriberClient::new( + Ok(SubscriberClient::from_raw_api( + api::subscriber_client::SubscriberClient::new( self.pubsub_authed_service(config).await?, ) .max_decoding_message_size(MAX_MESSAGE_SIZE), - }) + )) } } diff --git a/src/pubsub/emulator.rs b/src/pubsub/emulator.rs index 456fe70..4744298 100644 --- a/src/pubsub/emulator.rs +++ b/src/pubsub/emulator.rs @@ -139,6 +139,7 @@ impl EmulatorClient { let mut publisher = self.builder().build_pubsub_publisher(config).await?; publisher + .raw_api_mut() .create_topic(pubsub::api::Topic { name: pubsub::ProjectTopicName::new(self.project(), topic_name.as_ref()).into(), ..pubsub::api::Topic::default() diff --git a/src/pubsub/mod.rs b/src/pubsub/mod.rs index ca65c8f..43ece2c 100644 --- a/src/pubsub/mod.rs +++ b/src/pubsub/mod.rs @@ -3,12 +3,13 @@ //! Publishing and topic management is done through the [`PublisherClient`], while reading data and //! subscription management is done through the [`SubscriberClient`]. -use crate::{auth::grpc::AuthGrpcService, retry_policy::RetryPredicate}; +use crate::grpc::{Body, BoxBody, Bytes, DefaultGrpcImpl, GrpcService, StdError}; +use crate::retry_policy::RetryPredicate; use std::fmt::Display; use tracing::debug_span; // alias Status as this module's error type -pub use ::tonic::Status as Error; +pub use tonic::Status as Error; pub use client_builder::{BuildError, MakeConnection, PubSubConfig, Uri}; pub use publish_sink::{PublishConfig, PublishError, PublishTopicSink, SinkError}; @@ -40,78 +41,87 @@ pub mod api { /// /// This builds on top of the raw [gRPC publisher API](api::publisher_client::PublisherClient) /// to provide more ergonomic functionality -#[derive(Clone)] -pub struct PublisherClient { - inner: api::publisher_client::PublisherClient>, +#[derive(Debug, Clone)] +pub struct PublisherClient { + inner: api::publisher_client::PublisherClient, } -impl PublisherClient +impl PublisherClient { + /// Manually construct a new client. + /// + /// There are limited circumstances in which this is useful; consider instead using the builder + /// function [crate::builder::ClientBuilder::build_pubsub_publisher] + pub fn from_raw_api(client: api::publisher_client::PublisherClient) -> Self { + PublisherClient { inner: client } + } + + /// Access the underlying grpc api + pub fn raw_api(&self) -> &api::publisher_client::PublisherClient { + &self.inner + } + + /// Mutably access the underlying grpc api + pub fn raw_api_mut(&mut self) -> &mut api::publisher_client::PublisherClient { + &mut self.inner + } +} + +impl PublisherClient where - C: tower::Service + Clone + Send + Sync + 'static, - C::Response: hyper::client::connect::Connection - + tokio::io::AsyncRead - + tokio::io::AsyncWrite - + Send - + Unpin - + 'static, - C::Future: Send + Unpin + 'static, - C::Error: Into>, + S: GrpcService + Clone, + S::Error: Into, + S::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, { /// Create a sink which will publish [messages](api::PubsubMessage) to the given topic. /// /// See the type's [documentation](PublishTopicSink) for more details. - pub fn publish_topic_sink(&mut self, topic: ProjectTopicName) -> PublishTopicSink { - self.publish_topic_sink_config(topic, PublishConfig::default()) - } - - /// Create a sink with non-default config - // TODO(major semver) get rid of this method, always require config - pub fn publish_topic_sink_config( + pub fn publish_topic_sink( &mut self, topic: ProjectTopicName, config: PublishConfig, - ) -> PublishTopicSink { + ) -> PublishTopicSink { PublishTopicSink::new(self.inner.clone(), topic, config) } } -impl std::ops::Deref for PublisherClient { - type Target = - api::publisher_client::PublisherClient>; - - fn deref(&self) -> &Self::Target { - &self.inner - } -} - -impl std::ops::DerefMut for PublisherClient { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.inner - } -} - /// A client through which pubsub messages are consumed, and subscriptions are managed. Created /// from the [`build_pubsub_subscriber`](crate::builder::ClientBuilder::build_pubsub_subscriber) /// function. /// /// This is an interface built on top of the raw [gRPC subscriber /// API](api::subscriber_client::SubscriberClient) which provides more ergonomic functionality -#[derive(Clone)] -pub struct SubscriberClient { - inner: api::subscriber_client::SubscriberClient>, +#[derive(Debug, Clone)] +pub struct SubscriberClient { + inner: api::subscriber_client::SubscriberClient, +} + +impl SubscriberClient { + /// Manually construct a new client. + /// + /// There are limited circumstances in which this is useful; consider instead using the builder + /// function [crate::builder::ClientBuilder::build_pubsub_subscriber] + pub fn from_raw_api(client: api::subscriber_client::SubscriberClient) -> Self { + Self { inner: client } + } + + /// Access the underlying grpc api + pub fn raw_api(&self) -> &api::subscriber_client::SubscriberClient { + &self.inner + } + + /// Mutably access the underlying grpc api + pub fn raw_api_mut(&mut self) -> &mut api::subscriber_client::SubscriberClient { + &mut self.inner + } } -impl SubscriberClient +impl SubscriberClient where - C: tower::Service + Clone + Send + Sync + 'static, - C::Response: hyper::client::connect::Connection - + tokio::io::AsyncRead - + tokio::io::AsyncWrite - + Send - + Unpin - + 'static, - C::Future: Send + Unpin + 'static, - C::Error: Into>, + S: GrpcService + Clone, + S::Error: Into, + S::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, { /// Start a streaming subscription with the pubsub service. /// @@ -121,7 +131,7 @@ where &mut self, subscription: ProjectSubscriptionName, config: StreamSubscriptionConfig, - ) -> StreamSubscription { + ) -> StreamSubscription { let sub_name: String = subscription.clone().into(); let span = debug_span!("create_subscription", topic = sub_name); let _guard = span.enter(); @@ -129,21 +139,6 @@ where } } -impl std::ops::Deref for SubscriberClient { - type Target = - api::subscriber_client::SubscriberClient>; - - fn deref(&self) -> &Self::Target { - &self.inner - } -} - -impl std::ops::DerefMut for SubscriberClient { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.inner - } -} - /// A project and subscription name combined in a format expected by API calls, /// /// ``` diff --git a/src/pubsub/publish_sink.rs b/src/pubsub/publish_sink.rs index 25811db..574d295 100644 --- a/src/pubsub/publish_sink.rs +++ b/src/pubsub/publish_sink.rs @@ -1,6 +1,9 @@ -use super::{api, ProjectTopicName, PubSubRetryCheck}; +use super::{ + api::{self, publisher_client::PublisherClient as ApiPublisherClient}, + ProjectTopicName, PubSubRetryCheck, +}; use crate::{ - auth::grpc::AuthGrpcService, + grpc::{Body, BoxBody, Bytes, GrpcService, StdError}, retry_policy::{exponential_backoff, ExponentialBackoff, RetryOperation, RetryPolicy}, }; use futures::{future::BoxFuture, ready, stream, Sink, SinkExt, TryFutureExt}; @@ -9,7 +12,6 @@ use prost::Message; use std::{ cmp::Ordering, convert::Infallible, - error::Error as StdError, fmt, future::Future, pin::Pin, @@ -29,8 +31,6 @@ const MAX_MESSAGES_PER_PUBLISH: usize = 1000; const MAX_DATA_FIELD_BYTES: usize = 10 * MB; const MAX_PUBLISH_REQUEST_BYTES: usize = 10 * MB; -type ApiPublisherClient = - api::publisher_client::PublisherClient>; type Drain = futures::sink::Drain; type FlushOutput = (Si, Result<(), SinkError>); @@ -77,8 +77,8 @@ impl fmt::Display for SinkError { } } -impl StdError for SinkError { - fn source(&self) -> Option<&(dyn StdError + 'static)> { +impl std::error::Error for SinkError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { match self { SinkError::Publish(err) => Some(err as &_), SinkError::Response(err) => Some(err as &_), @@ -103,7 +103,6 @@ config_default! { /// Configuration for a [publish sink](super::PublisherClient::publish_topic_sink) /// request #[derive(Debug, Clone, Copy, Eq, PartialEq, serde::Deserialize)] - #[non_exhaustive] pub struct PublishConfig { /// The amount of time to wait for a publish request to succeed before timing out // TODO use 60sec default value from go lib, or 5 seconds plus backoff from java lib @@ -155,12 +154,12 @@ config_default! { /// [`with_response_sink`]: PublishTopicSink::with_response_sink #[pin_project(project=PublishTopicSinkProjection)] pub struct PublishTopicSink< - C = crate::DefaultConnector, + S = crate::grpc::DefaultGrpcImpl, Retry = ExponentialBackoff, ResponseSink: Sink = Drain, > { /// the underlying client used to execute the requests - client: ApiPublisherClient, + client: ApiPublisherClient, /// the publish request currently being populated with messages buffer: PublishBuffer, @@ -194,16 +193,13 @@ enum FlushState> { Flushing(#[pin] BoxFuture<'static, FlushOutput>), } -impl PublishTopicSink, Drain> { +impl PublishTopicSink, Drain> { /// Create a new `PublishTopicSink` with the default retry policy and no response sink - pub(super) fn new( - client: ApiPublisherClient, + pub(crate) fn new( + client: ApiPublisherClient, topic: ProjectTopicName, config: PublishConfig, - ) -> Self - where - C: crate::Connect + Clone + Send + Sync + 'static, - { + ) -> Self { PublishTopicSink { client, buffer: PublishBuffer::new(String::from(topic)), @@ -218,7 +214,7 @@ impl PublishTopicSink, Drain> { } } -impl> PublishTopicSink { +impl> PublishTopicSink { /// Set the sink to receive successful publishing responses for published messages. /// /// By default, the `PublishTopicSink` will not report when messages are successfully published. @@ -232,7 +228,7 @@ impl> PublishTopicSink(self, sink: Si) -> PublishTopicSink + pub fn with_response_sink(self, sink: Si) -> PublishTopicSink where Si: Sink, { @@ -251,7 +247,7 @@ impl> PublishTopicSink(self, retry_policy: R) -> PublishTopicSink + pub fn with_retry_policy(self, retry_policy: R) -> PublishTopicSink where R: RetryPolicy, { @@ -266,17 +262,13 @@ impl> PublishTopicSink Sink for PublishTopicSink +impl Sink for PublishTopicSink where - C: tower::Service + Clone + Send + Sync + 'static, - C::Response: hyper::client::connect::Connection - + tokio::io::AsyncRead - + tokio::io::AsyncWrite - + Send - + Unpin - + 'static, - C::Future: Send + Unpin + 'static, - C::Error: Into>, + S: GrpcService + Clone + Send + 'static, + S::Future: Send + 'static, + S::Error: Into, + S::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, // TODO(type_alias_impl_trait) remove most of these 'static (and Send?) bounds Retry: RetryPolicy + 'static, Retry::RetryOp: Send + 'static, @@ -320,17 +312,13 @@ where // some methods are implemented against a projection instead of the base type to make nested // borrowing/pinning in callers easier -impl<'pin, C, Retry, ResponseSink> PublishTopicSinkProjection<'pin, C, Retry, ResponseSink> +impl<'pin, S, Retry, ResponseSink> PublishTopicSinkProjection<'pin, S, Retry, ResponseSink> where - C: tower::Service + Clone + Send + Sync + 'static, - C::Response: hyper::client::connect::Connection - + tokio::io::AsyncRead - + tokio::io::AsyncWrite - + Send - + Unpin - + 'static, - C::Future: Send + Unpin + 'static, - C::Error: Into>, + S: GrpcService + Clone + Send + 'static, + S::Future: Send + 'static, + S::Error: Into, + S::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, Retry: RetryPolicy + 'static, Retry::RetryOp: Send + 'static, >::Sleep: Send + 'static, @@ -420,7 +408,7 @@ where } fn flush( - client: &mut ApiPublisherClient, + client: &mut ApiPublisherClient, mut request: api::PublishRequest, mut response_sink: ResponseSink, retry_policy: &mut Retry, @@ -758,11 +746,11 @@ mod test { } } - fn dummy_client() -> ApiPublisherClient { + fn dummy_client() -> ApiPublisherClient { // by connecting to the endpoint lazily, this client will only work until the first request // is made (then it will error). That's good enough for testing certain functionality // that doesn't require the requests themselves, like validity checking - ApiPublisherClient::new(crate::auth::grpc::AuthGrpcService::new( + ApiPublisherClient::new(crate::grpc::DefaultGrpcImpl::new( tonic::transport::channel::Endpoint::from_static("https://localhost").connect_lazy(), None, vec![], @@ -996,6 +984,7 @@ mod test { .await?; publisher + .raw_api_mut() .create_topic(api::Topic { name: project_topic.clone().into(), ..api::Topic::default() @@ -1008,6 +997,7 @@ mod test { .await?; subscriber + .raw_api_mut() .create_subscription(api::Subscription { name: project_subscription.clone().into(), topic: project_topic.clone().into(), @@ -1017,7 +1007,7 @@ mod test { let (response_sink, responses) = futures::channel::mpsc::unbounded(); let publish_topic_sink = publisher - .publish_topic_sink(project_topic.clone()) + .publish_topic_sink(project_topic.clone(), PublishConfig::default()) .with_response_sink(response_sink); // send 10 messages, each large enough such that at most 4 messages fit into a single @@ -1038,6 +1028,7 @@ mod test { while received_messages.len() < sent_messages.len() { received_messages.extend( subscriber + .raw_api_mut() .pull(api::PullRequest { subscription: project_subscription.clone().into(), max_messages: 10, @@ -1098,6 +1089,7 @@ mod test { .await?; publisher + .raw_api_mut() .create_topic(api::Topic { name: project_topic.clone().into(), ..api::Topic::default() @@ -1106,7 +1098,7 @@ mod test { let (user_sink, mut user_sink_receiver) = futures::channel::mpsc::unbounded(); let mut publish_sink = publisher - .publish_topic_sink(project_topic.clone()) + .publish_topic_sink(project_topic.clone(), PublishConfig::default()) .with_response_sink(user_sink); let message = api::PubsubMessage { diff --git a/src/pubsub/streaming_subscription.rs b/src/pubsub/streaming_subscription.rs index 4fb1bad..18c4f39 100644 --- a/src/pubsub/streaming_subscription.rs +++ b/src/pubsub/streaming_subscription.rs @@ -16,7 +16,7 @@ use tonic::metadata::MetadataValue; use tracing::{debug, trace_span, Instrument}; use crate::{ - auth::grpc::AuthGrpcService, + grpc::{Body, BoxBody, Bytes, GrpcService, StdError}, pubsub::{api, PubSubRetryCheck}, retry_policy::{exponential_backoff, ExponentialBackoff, RetryOperation, RetryPolicy}, }; @@ -265,9 +265,11 @@ fn create_streaming_pull_request_stream( /// The stream returned by the /// [`stream_subscription`](crate::pubsub::SubscriberClient::stream_subscription) function #[pin_project] -pub struct StreamSubscription> -{ - state: StreamState, +pub struct StreamSubscription< + S = crate::grpc::DefaultGrpcImpl, + R = ExponentialBackoff, +> { + state: StreamState, // reserve the right to be !Unpin in the future without a major version bump _p: std::marker::PhantomPinned, } @@ -279,10 +281,9 @@ pub struct StreamSubscription` which then prohibits moving `self`, so no builder methods /// could be called after streaming -enum StreamState { +enum StreamState { Initialized { - client: - api::subscriber_client::SubscriberClient>, + client: api::subscriber_client::SubscriberClient, subscription: String, config: StreamSubscriptionConfig, retry_policy: R, @@ -294,11 +295,9 @@ enum StreamState { ), } -impl StreamSubscription { +impl StreamSubscription { pub(super) fn new( - client: api::subscriber_client::SubscriberClient< - AuthGrpcService, - >, + client: api::subscriber_client::SubscriberClient, subscription: String, config: StreamSubscriptionConfig, ) -> Self { @@ -330,7 +329,7 @@ impl StreamSubscription { } } -impl StreamSubscription { +impl StreamSubscription { /// Set the [`RetryPolicy`] to use for this streaming subscription. /// /// The stream will be reconnected if the policy indicates that an encountered @@ -338,7 +337,7 @@ impl StreamSubscription { // Because `poll_next` requires `Pin<&mut Self>`, this function cannot be called after the // stream has started because it moves `self`. That means that the retry policy can only be // changed before the polling starts, and is fixed from that point on - pub fn with_retry_policy(self, new_retry_policy: R) -> StreamSubscription + pub fn with_retry_policy(self, new_retry_policy: R) -> StreamSubscription where R: RetryPolicy<(), tonic::Status>, { @@ -366,17 +365,13 @@ impl StreamSubscription { } } -impl Stream for StreamSubscription +impl Stream for StreamSubscription where - C: tower::Service + Clone + Send + Sync + 'static, - C::Response: hyper::client::connect::Connection - + tokio::io::AsyncRead - + tokio::io::AsyncWrite - + Send - + Unpin - + 'static, - C::Future: Send + Unpin + 'static, - C::Error: Into>, + S: GrpcService + Send + 'static, + S::Future: Send + 'static, + S::Error: Into, + S::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, R: RetryPolicy<(), tonic::Status> + Send + 'static, R::RetryOp: Send + 'static, >::Sleep: Send + 'static, @@ -425,24 +420,18 @@ where /// /// The stream will internally reconnect on error if the given retry policy indicates the /// error is retriable -fn stream_from_client( - mut client: api::subscriber_client::SubscriberClient< - AuthGrpcService, - >, +fn stream_from_client( + mut client: api::subscriber_client::SubscriberClient, subscription: String, config: StreamSubscriptionConfig, mut retry_policy: R, ) -> impl Stream> + Send + 'static where - C: tower::Service + Clone + Send + Sync + 'static, - C::Response: hyper::client::connect::Connection - + tokio::io::AsyncRead - + tokio::io::AsyncWrite - + Send - + Unpin - + 'static, - C::Future: Send + Unpin + 'static, - C::Error: Into>, + S: GrpcService + Send + 'static, + S::Future: Send + 'static, + S::Error: Into, + S::ResponseBody: Body + Send + 'static, + ::Error: Into + Send, R: RetryPolicy<(), tonic::Status> + Send + 'static, R::RetryOp: Send + 'static, >::Sleep: Send + 'static, diff --git a/src/storage.rs b/src/storage.rs index b4bb2cc..b84f775 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -154,23 +154,12 @@ pub enum ObjectError { } /// A client used to interact with Google Cloud Storage -pub struct StorageClient { - client: Client, - auth: Option>, +pub struct StorageClient { + client: Client>, + auth: Option, } -impl StorageClient -where - C: tower::Service + Clone + Send + Sync + 'static, - C::Response: hyper::client::connect::Connection - + tokio::io::AsyncRead - + tokio::io::AsyncWrite - + Send - + Unpin - + 'static, - C::Future: Send + Unpin + 'static, - C::Error: Into>, -{ +impl StorageClient { /// Add authentication to the request and send it, awaiting the response. The response will be /// collected into a single memory allocation (not a streamed body) async fn send_request( @@ -338,14 +327,11 @@ where } } -impl builder::ClientBuilder -where - C: Clone, -{ +impl builder::ClientBuilder { /// Create a client for access Google Cloud Storage - pub fn build_storage_client(&self) -> StorageClient { + pub fn build_storage_client(&self) -> StorageClient { StorageClient { - client: self.client.clone(), + client: hyper::client::Client::builder().build(crate::builder::https_connector()), auth: self.auth.clone(), } } diff --git a/tests/bigtable_client.rs b/tests/bigtable_client.rs index 08713b8..a80b5b9 100644 --- a/tests/bigtable_client.rs +++ b/tests/bigtable_client.rs @@ -88,7 +88,6 @@ mod bigtable_client_tests { assert_eq!("row1-key", row.key); assert_eq!(1, row.families.len()); assert_eq!("fam1", row.families[0].name); - dbg!(&row.families); assert_eq!(2, row.families[0].columns.len()); assert_eq!("col1", row.families[0].columns[0].qualifier); assert_eq!("data1", row.families[0].columns[0].cells[0].value); @@ -145,19 +144,19 @@ mod bigtable_client_tests { row.most_recent_cells().map(|c| c.value).collect::>() ); - let req = ReadRowsRequest { - table_name: format!( + let req = { + let mut r = ReadRowsRequest::default(); + r.table_name = format!( "projects/{}/instances/{}/tables/{table_name}", emulator.project(), emulator.instance() - ), - rows: Some(api::bigtable::v2::RowSet::default().with_key("row1-key")), - ..Default::default() + ); + r.rows = Some(api::bigtable::v2::RowSet::default().with_key("row1-key")); + r }; let rows: Vec<_> = client.read_rows(req).try_collect().await.unwrap(); assert_eq!(1, rows.len()); let row = &rows[0]; - dbg!(row); assert_eq!(2, row.families[0].columns[0].cells.len()); assert_eq!( vec!["data2".as_bytes()], diff --git a/tests/pubsub_client.rs b/tests/pubsub_client.rs index 2f6a1b7..a293c54 100644 --- a/tests/pubsub_client.rs +++ b/tests/pubsub_client.rs @@ -9,88 +9,59 @@ mod pubsub_client_tests { }; use ya_gcp::pubsub::{ self, api::PubsubMessage, emulator::Emulator, ProjectSubscriptionName, ProjectTopicName, - PublisherClient, SinkError, StreamSubscriptionConfig, + PublisherClient, SinkError, StreamSubscriptionConfig, SubscriberClient, }; /// Helper to create a new topic request. - async fn create_dummy_topic( - client: &mut PublisherClient, + async fn create_dummy_topic( + client: &mut PublisherClient, project_name: &str, topic: &str, - ) -> Result, tonic::Status> - where - C: tower::Service + Clone + Send + Sync + 'static, - C::Response: hyper::client::connect::Connection - + tokio::io::AsyncRead - + tokio::io::AsyncWrite - + Send - + Unpin - + 'static, - C::Future: Send + Unpin + 'static, - C::Error: Into>, - { - let request = pubsub::api::Topic { - name: format!("projects/{}/topics/{}", project_name, topic), - ..pubsub::api::Topic::default() + ) -> Result, tonic::Status> { + let request = { + let mut t = pubsub::api::Topic::default(); + t.name = format!("projects/{}/topics/{}", project_name, topic); + t }; - client.create_topic(request).await + client.raw_api_mut().create_topic(request).await } async fn create_dummy_subscription( - client: &mut pubsub::api::subscriber_client::SubscriberClient< - impl tonic::client::GrpcService< - tonic::body::BoxBody, - Error = ya_gcp::auth::grpc::AuthGrpcError< - tonic::transport::Error, - yup_oauth2::Error, - >, - ResponseBody = tonic::transport::Body, - >, - >, + client: &mut SubscriberClient, project_name: &str, subscription_name: &str, topic_name: &str, ) -> Result, tonic::Status> { - let request = pubsub::api::Subscription { - name: ProjectSubscriptionName::new(project_name, subscription_name).into(), - topic: ProjectTopicName::new(project_name, topic_name).into(), - ..pubsub::api::Subscription::default() + let request = { + let mut sub = pubsub::api::Subscription::default(); + sub.name = ProjectSubscriptionName::new(project_name, subscription_name).into(); + sub.topic = ProjectTopicName::new(project_name, topic_name).into(); + sub }; - client.create_subscription(request).await + client.raw_api_mut().create_subscription(request).await } - async fn publish_data( - client: &mut PublisherClient, + async fn publish_data( + client: &mut PublisherClient, project_name: &str, topic_name: &str, messages: impl IntoIterator, BTreeMap)>, - ) -> Result, tonic::Status> - where - C: tower::Service + Clone + Send + Sync + 'static, - C::Response: hyper::client::connect::Connection - + tokio::io::AsyncRead - + tokio::io::AsyncWrite - + Send - + Unpin - + 'static, - C::Future: Send + Unpin + 'static, - C::Error: Into>, - { - let messages = messages - .into_iter() - .map(|(data, attributes)| pubsub::api::PubsubMessage { - data: ::prost::bytes::Bytes::from(data), - attributes, - message_id: Default::default(), - publish_time: None, - ordering_key: Default::default(), - }); + ) -> Result, tonic::Status> { + let messages = messages.into_iter().map(|(data, attributes)| { + let mut msg = pubsub::api::PubsubMessage::default(); + msg.data = ::prost::bytes::Bytes::from(data); + msg.attributes = attributes; + msg + }); let (tx, rx) = futures::channel::mpsc::unbounded(); let message_sink = client - .publish_topic_sink(ProjectTopicName::new(project_name, topic_name)) + .publish_topic_sink( + ProjectTopicName::new(project_name, topic_name), + Default::default(), + ) .with_response_sink(tx); futures::stream::iter(messages.map(Ok)) @@ -143,9 +114,10 @@ mod pubsub_client_tests { .unwrap(); assert_eq!( - pubsub::api::Topic { - name: format!("projects/{}/topics/{}", emulator.project(), topic_name), - ..Default::default() + { + let mut t = pubsub::api::Topic::default(); + t.name = format!("projects/{}/topics/{}", emulator.project(), topic_name); + t }, create_dummy_topic(&mut client, emulator.project(), topic_name) .await @@ -169,16 +141,24 @@ mod pubsub_client_tests { .await .unwrap(); - let request = pubsub::api::GetTopicRequest { - topic: format!("projects/{}/topics/{}", emulator.project(), topic_name), + let request = { + let mut r = pubsub::api::GetTopicRequest::default(); + r.topic = format!("projects/{}/topics/{}", emulator.project(), topic_name); + r }; assert_eq!( - pubsub::api::Topic { - name: format!("projects/{}/topics/{}", emulator.project(), topic_name), - ..Default::default() + { + let mut t = pubsub::api::Topic::default(); + t.name = format!("projects/{}/topics/{}", emulator.project(), topic_name); + t }, - client.get_topic(request).await.unwrap().into_inner() + client + .raw_api_mut() + .get_topic(request) + .await + .unwrap() + .into_inner() ); } @@ -235,18 +215,21 @@ mod pubsub_client_tests { .await .unwrap(); - let request = pubsub::api::ListTopicSubscriptionsRequest { - topic: format!("projects/{}/topics/{}", emulator.project(), topic_name), - page_size: 10, - page_token: Default::default(), + let request = { + let mut r = pubsub::api::ListTopicSubscriptionsRequest::default(); + r.topic = format!("projects/{}/topics/{}", emulator.project(), topic_name); + r.page_size = 10; + r }; - let response = client.list_topic_subscriptions(request).await; + let response = client.raw_api_mut().list_topic_subscriptions(request).await; assert_eq!( - pubsub::api::ListTopicSubscriptionsResponse { - subscriptions: vec![], - next_page_token: String::new(), + { + let mut r = pubsub::api::ListTopicSubscriptionsResponse::default(); + r.subscriptions = vec![]; + r.next_page_token = String::new(); + r }, response.unwrap().into_inner() ); @@ -324,10 +307,12 @@ mod pubsub_client_tests { .into_inner(); #[allow(deprecated)] - let request = pubsub::api::PullRequest { - subscription: response.name, - return_immediately: false, - max_messages: num_messages as i32, + let request = { + let mut r = pubsub::api::PullRequest::default(); + r.subscription = response.name; + r.return_immediately = false; + r.max_messages = num_messages as i32; + r }; let mut attributes = BTreeMap::default(); @@ -346,7 +331,7 @@ mod pubsub_client_tests { assert_eq!(message_ids.len(), num_messages); - let response = subscription_client.pull(request).await; + let response = subscription_client.raw_api_mut().pull(request).await; let mut received_messages = response.unwrap().into_inner().received_messages; let message = received_messages.pop().unwrap(); @@ -487,9 +472,9 @@ mod pubsub_client_tests { let read_messages = stream .take(num_messages) - .map_ok(|(_ack_token, msg)| pubsub::api::PubsubMessage { - publish_time: None, - ..msg + .map_ok(|(_ack_token, mut msg)| { + msg.publish_time = None; + msg }) .try_collect::>() .await @@ -791,43 +776,51 @@ mod pubsub_client_tests { // update the subscription with a DeadLetterPolicy so that the delivery counter engages subscription_client - .update_subscription(pubsub::api::UpdateSubscriptionRequest { - subscription: Some(pubsub::api::Subscription { - dead_letter_policy: Some(pubsub::api::DeadLetterPolicy { - dead_letter_topic: format!( - "projects/{}/topics/{}", - emulator.project(), - topic_name - ), - max_delivery_attempts: 5, - }), - ..subscription - }), - update_mask: Some(pubsub::api::FieldMask { + .raw_api_mut() + .update_subscription({ + let mut update = pubsub::api::UpdateSubscriptionRequest::default(); + update.subscription = Some({ + let mut sub = subscription.clone(); + sub.dead_letter_policy = Some({ + let mut d = pubsub::api::DeadLetterPolicy::default(); + d.dead_letter_topic = + format!("projects/{}/topics/{}", emulator.project(), topic_name); + d.max_delivery_attempts = 5; + d + }); + sub + }); + update.update_mask = Some(pubsub::api::FieldMask { paths: vec!["dead_letter_policy".into()], - }), + }); + update }) .await .unwrap(); // send 1 message to the publisher. this should be delivered again after a nack publish_client - .publish(pubsub::api::PublishRequest { - topic: topic.name, - messages: vec![pubsub::api::PubsubMessage { - data: "foobar".into(), - ..pubsub::api::PubsubMessage::default() - }], + .raw_api_mut() + .publish({ + let mut p = pubsub::api::PublishRequest::default(); + p.topic = topic.name; + p.messages = vec![{ + let mut m = pubsub::api::PubsubMessage::default(); + m.data = "foobar".into(); + m + }]; + p }) .await .unwrap(); let mut subscription_stream = subscription_client.stream_subscription( ProjectSubscriptionName::new(emulator.project(), subscription_name), - StreamSubscriptionConfig { + { + let mut c = StreamSubscriptionConfig::default(); // set a large general deadline to prevent inadvertent delivery - stream_ack_deadline: Duration::from_secs(600), - ..StreamSubscriptionConfig::default() + c.stream_ack_deadline = Duration::from_secs(600); + c }, ); @@ -888,43 +881,51 @@ mod pubsub_client_tests { // update the subscription with a DeadLetterPolicy so that the delivery counter engages subscription_client - .update_subscription(pubsub::api::UpdateSubscriptionRequest { - subscription: Some(pubsub::api::Subscription { - dead_letter_policy: Some(pubsub::api::DeadLetterPolicy { - dead_letter_topic: format!( - "projects/{}/topics/{}", - emulator.project(), - topic_name - ), - max_delivery_attempts: 5, - }), - ..subscription - }), - update_mask: Some(pubsub::api::FieldMask { + .raw_api_mut() + .update_subscription({ + let mut update = pubsub::api::UpdateSubscriptionRequest::default(); + update.subscription = Some({ + let mut sub = subscription.clone(); + sub.dead_letter_policy = Some({ + let mut d = pubsub::api::DeadLetterPolicy::default(); + d.dead_letter_topic = + format!("projects/{}/topics/{}", emulator.project(), topic_name); + d.max_delivery_attempts = 5; + d + }); + sub + }); + update.update_mask = Some(pubsub::api::FieldMask { paths: vec!["dead_letter_policy".into()], - }), + }); + update }) .await .unwrap(); // send 1 message to the publisher. this should be delivered again after its deadline publish_client - .publish(pubsub::api::PublishRequest { - topic: topic.name, - messages: vec![pubsub::api::PubsubMessage { - data: "foobar".into(), - ..pubsub::api::PubsubMessage::default() - }], + .raw_api_mut() + .publish({ + let mut r = pubsub::api::PublishRequest::default(); + r.topic = topic.name; + r.messages = vec![{ + let mut m = pubsub::api::PubsubMessage::default(); + m.data = "foobar".into(); + m + }]; + r }) .await .unwrap(); let mut subscription_stream = subscription_client.stream_subscription( ProjectSubscriptionName::new(emulator.project(), subscription_name), - StreamSubscriptionConfig { + { + let mut c = StreamSubscriptionConfig::default(); // set a large general deadline to prevent inadvertent delivery - stream_ack_deadline: Duration::from_secs(600), - ..StreamSubscriptionConfig::default() + c.stream_ack_deadline = Duration::from_secs(600); + c }, ); @@ -996,12 +997,16 @@ mod pubsub_client_tests { // send 1 message to the publisher to get an ack token publish_client - .publish(pubsub::api::PublishRequest { - topic: topic.name, - messages: vec![pubsub::api::PubsubMessage { - data: "foobar".into(), - ..pubsub::api::PubsubMessage::default() - }], + .raw_api_mut() + .publish({ + let mut p = pubsub::api::PublishRequest::default(); + p.topic = topic.name; + p.messages = vec![{ + let mut m = pubsub::api::PubsubMessage::default(); + m.data = "foobar".into(); + m + }]; + p }) .await .unwrap();