From a4f633eee3d3d5bfe17e224a0c810ce678378e55 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 08:42:41 +0000 Subject: [PATCH 1/4] fix(deps): update cargo pre-1.0 packages --- Cargo.lock | 108 +++++++++++++++++++-------------------- apollo-router/Cargo.toml | 40 +++++++-------- xtask/Cargo.lock | 6 +-- xtask/Cargo.toml | 2 +- 4 files changed, 78 insertions(+), 78 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 404a007163..ceea84c340 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -280,7 +280,7 @@ dependencies = [ "aws-sigv4", "aws-types", "axum", - "base64 0.21.2", + "base64 0.21.4", "bloomfilter", "brotli", "buildstructor", @@ -359,7 +359,7 @@ dependencies = [ "router-bridge", "rstack", "rust-embed", - "rustls 0.21.6", + "rustls 0.21.7", "rustls-pemfile", "schemars", "serde", @@ -367,7 +367,7 @@ dependencies = [ "serde_json_bytes", "serde_urlencoded", "serde_yaml", - "sha1 0.10.5", + "sha1 0.10.6", "sha2", "shellexpand", "similar-asserts", @@ -564,9 +564,9 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b74f44609f0f91493e3082d3734d98497e094777144380ea4db9f9905dd5b6" +checksum = "bb42b2197bf15ccb092b62c74515dbd8b86d0effd934795f6687c93b6e679a2c" dependencies = [ "brotli", "flate2", @@ -818,7 +818,7 @@ dependencies = [ "hyper-rustls", "lazy_static", "pin-project-lite", - "rustls 0.21.6", + "rustls 0.21.7", "tokio", "tower", "tracing", @@ -963,7 +963,7 @@ checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ "async-trait", "axum-core", - "base64 0.21.2", + "base64 0.21.4", "bitflags 1.3.2", "bytes", "futures-util", @@ -982,7 +982,7 @@ dependencies = [ "serde_json", "serde_path_to_error", "serde_urlencoded", - "sha1 0.10.5", + "sha1 0.10.6", "sync_wrapper", "tokio", "tokio-tungstenite", @@ -1037,9 +1037,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" [[package]] name = "base64-simd" @@ -1969,7 +1969,7 @@ dependencies = [ "sec1", "serde", "serde_bytes", - "sha1 0.10.5", + "sha1 0.10.6", "sha2", "signature 1.6.4", "spki", @@ -2561,7 +2561,7 @@ dependencies = [ "parking_lot 0.12.1", "rand 0.8.5", "redis-protocol", - "rustls 0.21.6", + "rustls 0.21.7", "rustls-native-certs", "rustls-webpki", "semver 1.0.18", @@ -2968,7 +2968,7 @@ dependencies = [ "http", "httpdate", "mime", - "sha1 0.10.5", + "sha1 0.10.6", ] [[package]] @@ -3179,7 +3179,7 @@ dependencies = [ "http", "hyper", "log", - "rustls 0.21.6", + "rustls 0.21.7", "rustls-native-certs", "tokio", "tokio-rustls 0.24.1", @@ -3393,9 +3393,9 @@ dependencies = [ [[package]] name = "jsonpath-rust" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b55563e28c54b1cc0d7eb92475cf9e210cd58e2fce9fabbc0cb5bb1136b4ab3" +checksum = "4a51ce4ed9d2d91361df55efafdd6115ecc0147ccfdb8b0e8b6d696d068a01b5" dependencies = [ "pest", "pest_derive", @@ -3422,7 +3422,7 @@ checksum = "2a071f4f7efc9a9118dfb627a0a94ef247986e1ab8606a4c806ae2b3aa3b6978" dependencies = [ "ahash", "anyhow", - "base64 0.21.2", + "base64 0.21.4", "bytecount", "fancy-regex", "fraction", @@ -3448,7 +3448,7 @@ version = "8.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" dependencies = [ - "base64 0.21.2", + "base64 0.21.4", "pem", "ring", "serde", @@ -3522,9 +3522,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.147" +version = "0.2.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" [[package]] name = "libfuzzer-sys" @@ -3646,9 +3646,9 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "lru" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eedb2bdbad7e0634f83989bf596f497b070130daaa398ab22d84c39e266deec5" +checksum = "a4a83fb7698b3643a0e34f9ae6f2e8f0178c0fd42f8b59d493aa271ff3a5bf21" dependencies = [ "hashbrown 0.14.0", ] @@ -4487,9 +4487,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12cc1b0bf1727a77a54b6654e7b5f1af8604923edc8b81885f8ec92f9e3f0a05" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -5001,11 +5001,11 @@ checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "reqwest" -version = "0.11.19" +version = "0.11.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20b9b67e2ca7dd9e9f9285b759de30ff538aab981abaaf7bc9bd90b84a0126c3" +checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1" dependencies = [ - "base64 0.21.2", + "base64 0.21.4", "bytes", "encoding_rs", "futures-core", @@ -5022,7 +5022,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.21.6", + "rustls 0.21.7", "rustls-native-certs", "rustls-pemfile", "serde", @@ -5348,9 +5348,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.6" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1feddffcfcc0b33f5c6ce9a29e341e4cd59c3f78e7ee45f4a40c038b1d6cbb" +checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" dependencies = [ "log", "ring", @@ -5376,7 +5376,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.2", + "base64 0.21.4", ] [[package]] @@ -5450,9 +5450,9 @@ dependencies = [ [[package]] name = "schemars" -version = "0.8.12" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02c613288622e5f0c3fdc5dbd4db1c5fbe752746b1d1a56a0630b78fd00de44f" +checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" dependencies = [ "dyn-clone", "schemars_derive", @@ -5463,9 +5463,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.12" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109da1e6b197438deb6db99952990c7f959572794b80ff93707d55a232545e7c" +checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" dependencies = [ "proc-macro2", "quote", @@ -5601,12 +5601,12 @@ dependencies = [ [[package]] name = "serde_json_bytes" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46deda3f831d90694634ede6f2f9b956bec326a67499333c7fc3943832d06050" +checksum = "feb260b2939374fad6f939f803662d4971d03395fcd03752b674bdba06565779" dependencies = [ "bytes", - "indexmap 1.9.3", + "indexmap 2.0.0", "serde", "serde_json", ] @@ -5703,9 +5703,9 @@ dependencies = [ [[package]] name = "sha1" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures", @@ -6364,7 +6364,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.6", + "rustls 0.21.7", "tokio", ] @@ -6395,13 +6395,13 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.20.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2dbec703c26b00d74844519606ef15d09a7d6857860f84ad223dec002ddea2" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", - "rustls 0.21.6", + "rustls 0.21.7", "rustls-native-certs", "tokio", "tokio-rustls 0.24.1", @@ -6410,9 +6410,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d" dependencies = [ "bytes", "futures-core", @@ -6510,7 +6510,7 @@ checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" dependencies = [ "async-trait", "axum", - "base64 0.21.2", + "base64 0.21.4", "bytes", "futures-core", "futures-util", @@ -6566,9 +6566,9 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ae70283aba8d2a8b411c695c437fe25b8b5e44e23e780662002fc72fb47a82" +checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" dependencies = [ "async-compression", "bitflags 2.4.0", @@ -6765,9 +6765,9 @@ dependencies = [ [[package]] name = "tungstenite" -version = "0.20.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e862a1c4128df0112ab625f55cd5c934bcb4312ba80b39ae4b4835a3fd58e649" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" dependencies = [ "byteorder", "bytes", @@ -6776,8 +6776,8 @@ dependencies = [ "httparse", "log", "rand 0.8.5", - "rustls 0.21.6", - "sha1 0.10.5", + "rustls 0.21.7", + "sha1 0.10.6", "thiserror", "url", "utf-8", @@ -7398,7 +7398,7 @@ checksum = "c6f71803d3a1c80377a06221e0530be02035d5b3e854af56c6ece7ac20ac441d" dependencies = [ "assert-json-diff", "async-trait", - "base64 0.21.2", + "base64 0.21.4", "deadpool", "futures", "futures-timer", diff --git a/apollo-router/Cargo.toml b/apollo-router/Cargo.toml index 7bde61d551..4bffe5983f 100644 --- a/apollo-router/Cargo.toml +++ b/apollo-router/Cargo.toml @@ -57,7 +57,7 @@ apollo-compiler = "0.11.2" apollo-encoder = "0.7.0" apollo-parser = "0.6.2" arc-swap = "1.6.0" -async-compression = { version = "0.4.1", features = [ +async-compression = { version = "0.4.3", features = [ "tokio", "brotli", "gzip", @@ -65,9 +65,9 @@ async-compression = { version = "0.4.1", features = [ ] } async-trait = "0.1.73" axum = { version = "0.6.20", features = ["headers", "json", "original-uri"] } -base64 = "0.21.2" +base64 = "0.21.4" bloomfilter = "1.0.12" -buildstructor = "0.5.3" +buildstructor = "0.5.4" bytes = "1.5.0" clap = { version = "4.4.5", default-features = false, features = [ "env", @@ -102,13 +102,13 @@ hyper-rustls = { version = "0.24.1", features = ["http1", "http2"] } indexmap = { version = "2.0.0", features = ["serde"] } itertools = "0.11.0" jsonpath_lib = "0.3.0" -jsonpath-rust = "0.3.1" +jsonpath-rust = "0.3.2" jsonschema = { version = "0.17.1", default-features = false } jsonwebtoken = "8.3.0" lazy_static = "1.4.0" -libc = "0.2.147" +libc = "0.2.148" linkme = "0.3.15" -lru = "0.11.0" +lru = "0.11.1" maplit = "1.0.2" mediatype = "0.19.15" mockall = "0.11.4" @@ -158,7 +158,7 @@ opentelemetry-zipkin = { version = "0.17.0", default-features = false, features ] } opentelemetry-prometheus = "0.12.0" paste = "1.0.14" -pin-project-lite = "0.2.12" +pin-project-lite = "0.2.13" prometheus = "0.13" prost = "0.11.9" prost-types = "0.11.9" @@ -167,7 +167,7 @@ rand = "0.8.5" rand_core = "0.6.4" rhai = { version = "1.16.2", features = ["sync", "serde", "internals"] } regex = "1.9.5" -reqwest = { version = "0.11.19", default-features = false, features = [ +reqwest = { version = "0.11.20", default-features = false, features = [ "rustls-tls", "rustls-native-certs", "json", @@ -176,13 +176,13 @@ reqwest = { version = "0.11.19", default-features = false, features = [ # note: this dependency should _always_ be pinned, prefix the version with an `=` router-bridge = "=0.5.5+v2.5.4" rust-embed = "6.8.1" -rustls = "0.21.6" +rustls = "0.21.7" rustls-pemfile = "1.0.3" -schemars = { version = "0.8.12", features = ["url"] } +schemars = { version = "0.8.15", features = ["url"] } shellexpand = "3.1.0" sha2 = "0.10.7" serde = { version = "1.0.188", features = ["derive", "rc"] } -serde_json_bytes = { version = "0.2.1", features = ["preserve_order"] } +serde_json_bytes = { version = "0.2.2", features = ["preserve_order"] } serde_json = { version = "1.0.107", features = [ "preserve_order", "float_roundtrip", @@ -195,7 +195,7 @@ sys-info = "0.9.1" thiserror = "1.0.48" tokio = { version = "1.32.0", features = ["full"] } tokio-stream = { version = "0.1.14", features = ["sync", "net"] } -tokio-util = { version = "0.7.8", features = ["net", "codec", "time"] } +tokio-util = { version = "0.7.9", features = ["net", "codec", "time"] } tonic = { version = "0.8.3", features = [ "transport", "tls", @@ -203,7 +203,7 @@ tonic = { version = "0.8.3", features = [ "gzip", ] } tower = { version = "0.4.13", features = ["full"] } -tower-http = { version = "0.4.3", features = [ +tower-http = { version = "0.4.4", features = [ "add-extension", "trace", "cors", @@ -227,7 +227,7 @@ uuid = { version = "1.4.1", features = ["serde", "v4"] } yaml-rust = "0.4.5" wiremock = "0.5.19" wsl = "0.1.0" -tokio-tungstenite = { version = "0.20.0", features = ["rustls-tls-native-roots"] } +tokio-tungstenite = { version = "0.20.1", features = ["rustls-tls-native-roots"] } tokio-rustls = "0.24.1" http-serde = "1.1.3" hmac = "0.12.1" @@ -237,11 +237,11 @@ brotli = "3.3.4" zstd = "0.12.4" zstd-safe = "6.0.6" # note: AWS dependencies should always use the same version -aws-sigv4 = "0.56.0" -aws-credential-types = "0.56.0" -aws-config = "0.56.0" -aws-types = "0.56.0" -sha1 = "0.10.5" +aws-sigv4 = "0.56.1" +aws-credential-types = "0.56.1" +aws-config = "0.56.1" +aws-types = "0.56.1" +sha1 = "0.10.6" [target.'cfg(macos)'.dependencies] uname = "0.1.1" @@ -270,7 +270,7 @@ once_cell = "1.18.0" p256 = "0.12.0" rand_core = "0.6.4" redis = { version = "0.21.7", features = ["tokio-comp"] } -reqwest = { version = "0.11.19", default-features = false, features = [ +reqwest = { version = "0.11.20", default-features = false, features = [ "json", "stream", ] } diff --git a/xtask/Cargo.lock b/xtask/Cargo.lock index 503885d102..70bbd155e3 100644 --- a/xtask/Cargo.lock +++ b/xtask/Cargo.lock @@ -216,14 +216,14 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.26" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", - "winapi", + "windows-targets 0.48.5", ] [[package]] diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 0c3655bb11..6023fdd2f9 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -16,7 +16,7 @@ cargo_metadata = "0.17" # Only use the `clock` features of `chrono` to avoid the `time` dependency # impacted by CVE-2020-26235. https://github.com/chronotope/chrono/issues/602 # and https://github.com/chronotope/chrono/issues/1073 will explain more. -chrono = { version = "0.4.26", default-features = false, features = ["clock"] } +chrono = { version = "0.4.31", default-features = false, features = ["clock"] } console = "0.15.7" dialoguer = "0.10.4" flate2 = "1" From b1859158246edc8cb798f262f18f8e49f71078e3 Mon Sep 17 00:00:00 2001 From: Jeremy Lempereur Date: Tue, 26 Sep 2023 11:38:37 +0200 Subject: [PATCH 2/4] Coprocessors: Allow JSON and String body shapes for ControlFlow::Break (#3806) This PR fixes a regression that would prevent coprocessor writers to ControlFlow::Break with a body `String`. --- .../fix_igni_coprocessor_error_body_fix.md | 16 ++ apollo-router/src/plugins/coprocessor/mod.rs | 37 +++-- apollo-router/src/plugins/coprocessor/test.rs | 142 ++++++++++++++++++ 3 files changed, 185 insertions(+), 10 deletions(-) create mode 100644 .changesets/fix_igni_coprocessor_error_body_fix.md diff --git a/.changesets/fix_igni_coprocessor_error_body_fix.md b/.changesets/fix_igni_coprocessor_error_body_fix.md new file mode 100644 index 0000000000..252fe90240 --- /dev/null +++ b/.changesets/fix_igni_coprocessor_error_body_fix.md @@ -0,0 +1,16 @@ +### Coprocessors: Allow to return with an error message ([PR #3806](https://github.com/apollographql/router/pull/3806)) + +As mentionned in the [Coprocessors documentation](https://www.apollographql.com/docs/router/customizations/coprocessor#terminating-a-client-request) you can (again) return an error message string in the body of a coprocessor request: + +```json +{ + "version": 1, + "stage": "SubgraphRequest", + "control": { + "break": 401 + }, + "body": "my error message" +} +``` + +By [@o0Ignition0o](https://github.com/o0Ignition0o) in https://github.com/apollographql/router/pull/3806 diff --git a/apollo-router/src/plugins/coprocessor/mod.rs b/apollo-router/src/plugins/coprocessor/mod.rs index 91b8a087de..50c768f9df 100644 --- a/apollo-router/src/plugins/coprocessor/mod.rs +++ b/apollo-router/src/plugins/coprocessor/mod.rs @@ -53,6 +53,8 @@ mod supergraph; pub(crate) const EXTERNAL_SPAN_NAME: &str = "external_plugin"; const POOL_IDLE_TIMEOUT_DURATION: Option = Some(Duration::from_secs(5)); +const COPROCESSOR_ERROR_EXTENSION: &str = "ERROR"; +const COPROCESSOR_DESERIALIZATION_ERROR_EXTENSION: &str = "EXTERNAL_DESERIALIZATION_ERROR"; type HTTPClientService = tower::timeout::Timeout>>; @@ -595,7 +597,7 @@ where ); tracing::debug!(?co_processor_result, "co-processor returned"); - let co_processor_output = co_processor_result?; + let mut co_processor_output = co_processor_result?; validate_coprocessor_output(&co_processor_output, PipelineStep::RouterRequest)?; // unwrap is safe here because validate_coprocessor_output made sure control is available @@ -611,21 +613,29 @@ where // At this point our body is a String. Try to get a valid JSON value from it let body_as_value = co_processor_output .body - .and_then(|b| serde_json::from_str(&b).ok()) + .as_ref() + .and_then(|b| serde_json::from_str(b).ok()) .unwrap_or(serde_json::Value::Null); // Now we have some JSON, let's see if it's the right "shape" to create a graphql_response. // If it isn't, we create a graphql error response - let graphql_response: crate::graphql::Response = serde_json::from_value(body_as_value) - .unwrap_or_else(|error| { + let graphql_response: crate::graphql::Response = match body_as_value { + serde_json::Value::Null => crate::graphql::Response::builder() + .errors(vec![Error::builder() + .message(co_processor_output.body.take().unwrap_or_default()) + .extension_code(COPROCESSOR_ERROR_EXTENSION) + .build()]) + .build(), + _ => serde_json::from_value(body_as_value).unwrap_or_else(|error| { crate::graphql::Response::builder() .errors(vec![Error::builder() .message(format!( "couldn't deserialize coprocessor output body: {error}" )) - .extension_code("EXTERNAL_DESERIALIZATION_ERROR") + .extension_code(COPROCESSOR_DESERIALIZATION_ERROR_EXTENSION) .build()]) .build() - }); + }), + }; let res = router::Response::builder() .errors(graphql_response.errors) @@ -936,17 +946,24 @@ where let res = { let graphql_response: crate::graphql::Response = - serde_json::from_value(co_processor_output.body.unwrap_or(serde_json::Value::Null)) - .unwrap_or_else(|error| { + match co_processor_output.body.unwrap_or(serde_json::Value::Null) { + serde_json::Value::String(s) => crate::graphql::Response::builder() + .errors(vec![Error::builder() + .message(s) + .extension_code(COPROCESSOR_ERROR_EXTENSION) + .build()]) + .build(), + value => serde_json::from_value(value).unwrap_or_else(|error| { crate::graphql::Response::builder() .errors(vec![Error::builder() .message(format!( "couldn't deserialize coprocessor output body: {error}" )) - .extension_code("EXTERNAL_DESERIALIZATION_ERROR") + .extension_code(COPROCESSOR_DESERIALIZATION_ERROR_EXTENSION) .build()]) .build() - }); + }), + }; let mut http_response = http::Response::builder() .status(code) diff --git a/apollo-router/src/plugins/coprocessor/test.rs b/apollo-router/src/plugins/coprocessor/test.rs index 3f4b50876e..c5f7b68de0 100644 --- a/apollo-router/src/plugins/coprocessor/test.rs +++ b/apollo-router/src/plugins/coprocessor/test.rs @@ -525,6 +525,69 @@ mod tests { ); } + #[tokio::test] + async fn external_plugin_subgraph_request_controlflow_break_with_message_string() { + let subgraph_stage = SubgraphStage { + request: SubgraphRequestConf { + headers: false, + context: false, + body: true, + uri: false, + method: false, + service_name: false, + }, + response: Default::default(), + }; + + // This will never be called because we will fail at the coprocessor. + let mock_subgraph_service = MockSubgraphService::new(); + + let mock_http_client = mock_with_callback(move |_: hyper::Request| { + Box::pin(async { + Ok(hyper::Response::builder() + .body(Body::from( + r#"{ + "version": 1, + "stage": "SubgraphRequest", + "control": { + "break": 200 + }, + "body": "my error message" + }"#, + )) + .unwrap()) + }) + }); + + let service = subgraph_stage.as_service( + mock_http_client, + mock_subgraph_service.boxed(), + "http://test".to_string(), + "my_subgraph_service_name".to_string(), + ); + + let request = subgraph::Request::fake_builder().build(); + + let response = service.oneshot(request).await.unwrap().response; + + assert_eq!(response.status(), http::StatusCode::OK); + + let actual_response = response.into_body(); + + assert_eq!( + actual_response, + serde_json::from_value(json!({ + "errors": [{ + "message": "my error message", + "extensions": { + "code": "ERROR" + } + }] + })) + .unwrap(), + ); + } + #[tokio::test] async fn external_plugin_subgraph_response() { let subgraph_stage = SubgraphStage { @@ -970,6 +1033,85 @@ mod tests { ); } + #[tokio::test] + async fn external_plugin_router_request_controlflow_break_with_message_string() { + let router_stage = RouterStage { + request: RouterRequestConf { + headers: true, + context: true, + body: true, + sdl: true, + path: true, + method: true, + }, + response: Default::default(), + }; + + let mock_router_service = MockRouterService::new(); + + let mock_http_client = mock_with_callback(move |req: hyper::Request| { + Box::pin(async { + let deserialized_request: Externalizable = + serde_json::from_slice(&hyper::body::to_bytes(req.into_body()).await.unwrap()) + .unwrap(); + + assert_eq!(EXTERNALIZABLE_VERSION, deserialized_request.version); + assert_eq!( + PipelineStep::RouterRequest.to_string(), + deserialized_request.stage + ); + + let input = json!( + { + "version": 1, + "stage": "RouterRequest", + "control": { + "break": 401 + }, + "id": "1b19c05fdafc521016df33148ad63c1b", + "body": "this is a test error", + } + ); + Ok(hyper::Response::builder() + .body(Body::from(serde_json::to_string(&input).unwrap())) + .unwrap()) + }) + }); + + let service = router_stage.as_service( + mock_http_client, + mock_router_service.boxed(), + "http://test".to_string(), + Arc::new("".to_string()), + ); + + let request = supergraph::Request::canned_builder().build().unwrap(); + + let response = service + .oneshot(request.try_into().unwrap()) + .await + .unwrap() + .response; + + assert_eq!(response.status(), http::StatusCode::UNAUTHORIZED); + let actual_response = serde_json::from_slice::( + &hyper::body::to_bytes(response.into_body()).await.unwrap(), + ) + .unwrap(); + + assert_eq!( + json!({ + "errors": [{ + "message": "this is a test error", + "extensions": { + "code": "ERROR" + } + }] + }), + actual_response + ); + } + #[tokio::test] async fn external_plugin_router_response() { let router_stage = RouterStage { From e48c1b7b6f4af56a295cf3d1d719c688515db873 Mon Sep 17 00:00:00 2001 From: Bryn Cooke Date: Tue, 26 Sep 2023 12:39:33 +0100 Subject: [PATCH 3/4] Use xlarge machines for linux builds (#3901) Currently we use medium machines for linux builds. These are underpowered to build the router. Currently release builds take near 50 minutes without caching. https://circleci.com/product/features/resource-classes/ Switch to xlarge for release builds. --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 3a91555b3f..575e979401 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -10,7 +10,7 @@ executors: amd_linux_build: &amd_linux_build_executor docker: - image: cimg/base:stable - resource_class: medium + resource_class: xlarge environment: CARGO_BUILD_JOBS: 4 RUST_TEST_THREADS: 6 From f6afe257489a11d5fbc197909dbd5779d8a7e234 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 13:35:30 +0000 Subject: [PATCH 4/4] fix(deps): update rust crate sha2 to 0.10.8 --- Cargo.lock | 4 ++-- apollo-router/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ceea84c340..692b09baae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5720,9 +5720,9 @@ checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", diff --git a/apollo-router/Cargo.toml b/apollo-router/Cargo.toml index 4bffe5983f..c22dca60ea 100644 --- a/apollo-router/Cargo.toml +++ b/apollo-router/Cargo.toml @@ -180,7 +180,7 @@ rustls = "0.21.7" rustls-pemfile = "1.0.3" schemars = { version = "0.8.15", features = ["url"] } shellexpand = "3.1.0" -sha2 = "0.10.7" +sha2 = "0.10.8" serde = { version = "1.0.188", features = ["derive", "rc"] } serde_json_bytes = { version = "0.2.2", features = ["preserve_order"] } serde_json = { version = "1.0.107", features = [