From 878dbc12714e5c0b8a476f7f0deb879ef9392d12 Mon Sep 17 00:00:00 2001 From: Maria Elisabeth Schreiber Date: Mon, 3 Jun 2024 11:59:25 -0600 Subject: [PATCH 1/9] docs: clarify subscription config (#5311) Co-authored-by: Edward Huang Co-authored-by: Jesse Rosenberger --- .../subscription-support.mdx | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/docs/source/executing-operations/subscription-support.mdx b/docs/source/executing-operations/subscription-support.mdx index 2c0029da65..6593044ca3 100644 --- a/docs/source/executing-operations/subscription-support.mdx +++ b/docs/source/executing-operations/subscription-support.mdx @@ -99,13 +99,20 @@ subscription: path: /subscriptions # The absolute URL path to use for subgraph subscription endpoints (Default: /ws) subgraphs: # Overrides subscription settings for individual subgraphs reviews: # Overrides settings for the 'reviews' subgraph - path: /ws # Absolute path that overrides '/subscriptions' defined above + path: /ws # Absolute path that overrides the preceding '/subscriptions' path for 'all' protocol: graphql_ws # The WebSocket-based subprotocol to use for subscription communication (Default: graphql_ws) heartbeat_interval: 10s # Optional and 'disable' by default, also supports 'enable' (set 5s interval) and custom values for intervals, e.g. '100ms', '10s', '1m'. ``` This example enables subscriptions in **passthrough mode**, which uses long-lived WebSocket connections. -Note: If your subgraph implementation (e.g. [DGS](https://netflix.github.io/dgs/)) can close idle connection, set `heartbest_interval` to keep connection alive. + + + +- Each `path` must be set as an absolute path. For example, given `http://localhost:8080/foo/bar/graphql/ws`, set the path configuration as `path: "/foo/bar/graphql/ws"`. +- Subgraph path configurations override the path configuration for `all` subgraphs. +- If your subgraph implementation (e.g. [DGS](https://netflix.github.io/dgs/)) can close idle connections, set `heartbeat_interval` to keep the connection alive. + + The router supports the following WebSocket subprotocols, specified via the `protocol` option: @@ -123,14 +130,14 @@ Your router creates a separate WebSocket connection for each client subscription -* Your router must use whichever subprotocol is expected by each of your subgraphs. -* To disambiguate between `graph-ws` and `graph_ws`: - * `graph-ws` (with a hyphen `-`) is the name of the [library](https://github.com/enisdenjo/graphql-ws) that uses the recommended `graphql_ws` (with un underscore `_`) WebSocket subprotocol. -* Each `path` must be set as an absolute path. For example, given `http://localhost:8080/foo/bar/graphql/ws`, set the absolute path as `path: "/foo/bar/graphql/ws"`. -* The `public_url` must include the configured `path` on the router. For example, given a server URL of `http://localhost:8080` and the router's `path` = `/my_callback`, then your `public_url` must append the `path` to the server: `http://localhost:8080/my_callback`. -* If you have a proxy in front of the router that redirects queries to the `path` configured in the router, you can specify another path for the `public_url`, for example `http://localhost:8080/external_path`. -* Given a `public_url`, the router appends a subscription id to the `public_url` to get {`http://localhost:8080/external_access/{subscription_id}`} then passes it directly to your subgraphs. -* If you don't specify the `path`, its default value is `/callback`, so you'll have to specify it in `public_url`. +- Your router must use whichever subprotocol is expected by each of your subgraphs. +- To disambiguate between `graph-ws` and `graph_ws`: + - `graph-ws` (with a hyphen `-`) is the name of the [library](https://github.com/enisdenjo/graphql-ws) that uses the recommended `graphql_ws` (with un underscore `_`) WebSocket subprotocol. +- Each `path` must be set as an absolute path. For example, given `http://localhost:8080/foo/bar/graphql/ws`, set the absolute path as `path: "/foo/bar/graphql/ws"`. +- The `public_url` must include the configured `path` on the router. For example, given a server URL of `http://localhost:8080` and the router's `path` = `/my_callback`, then your `public_url` must append the `path` to the server: `http://localhost:8080/my_callback`. +- If you have a proxy in front of the router that redirects queries to the `path` configured in the router, you can specify another path for the `public_url`, for example `http://localhost:8080/external_path`. +- Given a `public_url`, the router appends a subscription id to the `public_url` to get {`http://localhost:8080/external_access/{subscription_id}`} then passes it directly to your subgraphs. +- If you don't specify the `path`, its default value is `/callback`, so you'll have to specify it in `public_url`. From c8f1308384145bf8d1d8f6e9290060ae8891a075 Mon Sep 17 00:00:00 2001 From: Coenen Benjamin Date: Wed, 5 Jun 2024 16:52:28 +0200 Subject: [PATCH 2/9] fix(telemetry): rename the selector to get studio operation id (#5337) Signed-off-by: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com> --- .../config_bnjjj_fix_studio_selector.md | 14 +++++ ...nfiguration__tests__schema_generation.snap | 22 +++++--- .../plugins/telemetry/config_new/selectors.rs | 52 ++++++++----------- .../fixtures/jaeger-advanced.router.yaml | 4 +- .../tests/integration/telemetry/jaeger.rs | 2 +- .../telemetry/instrumentation/selectors.mdx | 3 +- 6 files changed, 55 insertions(+), 42 deletions(-) create mode 100644 .changesets/config_bnjjj_fix_studio_selector.md diff --git a/.changesets/config_bnjjj_fix_studio_selector.md b/.changesets/config_bnjjj_fix_studio_selector.md new file mode 100644 index 0000000000..07e558c185 --- /dev/null +++ b/.changesets/config_bnjjj_fix_studio_selector.md @@ -0,0 +1,14 @@ +### Rename the telemetry selector to get studio operation id ([PR #5337](https://github.com/apollographql/router/pull/5337)) + +We introduced a new `trace_id` selector format in `1.48.0` which has been misnamed because it's not a trace id but the Apollo Studio Operation ID. If you want to access to this selector, here is an example: + +```yaml +telemetry: + instrumentation: + spans: + router: + "studio.operation.id": + studio_operation_id: true +``` + +By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/5337 \ No newline at end of file diff --git a/apollo-router/src/configuration/snapshots/apollo_router__configuration__tests__schema_generation.snap b/apollo-router/src/configuration/snapshots/apollo_router__configuration__tests__schema_generation.snap index e46d0b68a3..3024bb9005 100644 --- a/apollo-router/src/configuration/snapshots/apollo_router__configuration__tests__schema_generation.snap +++ b/apollo-router/src/configuration/snapshots/apollo_router__configuration__tests__schema_generation.snap @@ -1,5 +1,6 @@ --- source: apollo-router/src/configuration/tests.rs +assertion_line: 26 expression: "&schema" --- { @@ -5028,6 +5029,20 @@ expression: "&schema" ], "type": "object" }, + { + "additionalProperties": false, + "description": "Apollo Studio operation id", + "properties": { + "studio_operation_id": { + "description": "Apollo Studio operation id", + "type": "boolean" + } + }, + "required": [ + "studio_operation_id" + ], + "type": "object" + }, { "additionalProperties": false, "description": "A value from context.", @@ -6882,13 +6897,6 @@ expression: "&schema" "datadog" ], "type": "string" - }, - { - "description": "Apollo Studio trace id", - "enum": [ - "apollo" - ], - "type": "string" } ] }, diff --git a/apollo-router/src/plugins/telemetry/config_new/selectors.rs b/apollo-router/src/plugins/telemetry/config_new/selectors.rs index 1316acf209..c23eecb747 100644 --- a/apollo-router/src/plugins/telemetry/config_new/selectors.rs +++ b/apollo-router/src/plugins/telemetry/config_new/selectors.rs @@ -35,8 +35,6 @@ pub(crate) enum TraceIdFormat { OpenTelemetry, /// Datadog trace ID, a u64. Datadog, - /// Apollo Studio trace id - Apollo, } #[derive(Deserialize, JsonSchema, Clone, Debug)] @@ -127,6 +125,11 @@ pub(crate) enum RouterSelector { /// The format of the trace ID. trace_id: TraceIdFormat, }, + /// Apollo Studio operation id + StudioOperationId { + /// Apollo Studio operation id + studio_operation_id: bool, + }, /// A value from context. ResponseContext { /// The response context key. @@ -566,20 +569,13 @@ impl Selector for RouterSelector { .map(opentelemetry::Value::from), RouterSelector::TraceId { trace_id: trace_id_format, - } => { - if let TraceIdFormat::Apollo = &trace_id_format { - return None; + } => trace_id().map(|id| { + match trace_id_format { + TraceIdFormat::OpenTelemetry => id.to_string(), + TraceIdFormat::Datadog => id.to_datadog(), } - trace_id().map(|id| { - match trace_id_format { - TraceIdFormat::OpenTelemetry => id.to_string(), - TraceIdFormat::Datadog => id.to_datadog(), - // It happens in the response - TraceIdFormat::Apollo => String::new(), - } - .into() - }) - } + .into() + }), RouterSelector::Baggage { baggage, default, .. } => get_baggage(baggage).or_else(|| default.maybe_to_otel_value()), @@ -636,20 +632,14 @@ impl Selector for RouterSelector { } RouterSelector::Static(val) => Some(val.clone().into()), RouterSelector::StaticField { r#static } => Some(r#static.clone().into()), - RouterSelector::TraceId { - trace_id: trace_id_format, - } => { - if let TraceIdFormat::Apollo = &trace_id_format { - response - .context - .get::<_, String>(APOLLO_OPERATION_ID) - .ok() - .flatten() - .map(opentelemetry::Value::from) - } else { - None - } - } + RouterSelector::StudioOperationId { + studio_operation_id, + } if *studio_operation_id => response + .context + .get::<_, String>(APOLLO_OPERATION_ID) + .ok() + .flatten() + .map(opentelemetry::Value::from), _ => None, } } @@ -1967,8 +1957,8 @@ mod test { #[test] fn test_router_studio_trace_id() { - let selector = RouterSelector::TraceId { - trace_id: TraceIdFormat::Apollo, + let selector = RouterSelector::StudioOperationId { + studio_operation_id: true, }; let ctx = crate::Context::new(); let _ = ctx.insert(APOLLO_OPERATION_ID, "42".to_string()).unwrap(); diff --git a/apollo-router/tests/integration/telemetry/fixtures/jaeger-advanced.router.yaml b/apollo-router/tests/integration/telemetry/fixtures/jaeger-advanced.router.yaml index 34f483eacf..e4c3ee0d57 100644 --- a/apollo-router/tests/integration/telemetry/fixtures/jaeger-advanced.router.yaml +++ b/apollo-router/tests/integration/telemetry/fixtures/jaeger-advanced.router.yaml @@ -44,8 +44,8 @@ telemetry: eq: - request_header: "head" - "test" - studio.trace.id: - trace_id: apollo + studio.operation.id: + studio_operation_id: true supergraph: attributes: graphql.operation.name: true diff --git a/apollo-router/tests/integration/telemetry/jaeger.rs b/apollo-router/tests/integration/telemetry/jaeger.rs index 2d7e3829de..b094558f38 100644 --- a/apollo-router/tests/integration/telemetry/jaeger.rs +++ b/apollo-router/tests/integration/telemetry/jaeger.rs @@ -414,7 +414,7 @@ fn verify_router_span_fields( ); assert_eq!( router_span - .select_path("$.tags[?(@.key == 'studio.trace.id')].value")? + .select_path("$.tags[?(@.key == 'studio.operation.id')].value")? .first(), Some(&&Value::String( "f60e643d7f52ecda23216f86409d7e2e5c3aa68c".to_string() diff --git a/docs/source/configuration/telemetry/instrumentation/selectors.mdx b/docs/source/configuration/telemetry/instrumentation/selectors.mdx index 303679dc4d..eff7447651 100644 --- a/docs/source/configuration/telemetry/instrumentation/selectors.mdx +++ b/docs/source/configuration/telemetry/instrumentation/selectors.mdx @@ -32,7 +32,8 @@ The router service is the initial entrypoint for all requests. It is HTTP centri | Selector | Defaultable | Values | Description | |--------------------|-------------|-------------------------------------------|--------------------------------------| -| `trace_id` | Yes | `open_telemetry`\|`datadog`\|`apollo` | The trace ID | +| `trace_id` | Yes | `open_telemetry`\|`datadog` | The trace ID | +| `studio_operation_id` | Yes | `true`|`false` | The Apollo Studio operation id | | `request_header` | Yes | | The name of the request header | | `response_header` | Yes | | The name of a response header | | `response_status` | Yes | `code`\|`reason` | The response status | From 2bc307231c18886d9e56b50527726ee0097f76c5 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 5 Jun 2024 18:56:33 +0300 Subject: [PATCH 3/9] General fixes to the changesets and CHANGELOG. --- .../config_bnjjj_fix_studio_selector.md | 6 ++- .changesets/feat_bryn_demand_control.md | 0 CHANGELOG.md | 44 +++++++++---------- 3 files changed, 26 insertions(+), 24 deletions(-) delete mode 100644 .changesets/feat_bryn_demand_control.md diff --git a/.changesets/config_bnjjj_fix_studio_selector.md b/.changesets/config_bnjjj_fix_studio_selector.md index 07e558c185..ca95af9e3c 100644 --- a/.changesets/config_bnjjj_fix_studio_selector.md +++ b/.changesets/config_bnjjj_fix_studio_selector.md @@ -1,6 +1,8 @@ ### Rename the telemetry selector to get studio operation id ([PR #5337](https://github.com/apollographql/router/pull/5337)) -We introduced a new `trace_id` selector format in `1.48.0` which has been misnamed because it's not a trace id but the Apollo Studio Operation ID. If you want to access to this selector, here is an example: +We introduced a new `trace_id` selector format in `1.48.0` which was misnamed. It's not a trace id, it's the Apollo Studio Operation ID. We've fixed this naming problem in this release. + +If you want to access this selector, here is an example: ```yaml telemetry: @@ -11,4 +13,4 @@ telemetry: studio_operation_id: true ``` -By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/5337 \ No newline at end of file +By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/5337 diff --git a/.changesets/feat_bryn_demand_control.md b/.changesets/feat_bryn_demand_control.md deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/CHANGELOG.md b/CHANGELOG.md index 49e3553c40..8135084cde 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,7 +40,7 @@ By [@bryncooke](https://github.com/bryncooke) in https://github.com/apollographq ### Ability to include Apollo Studio trace ID on tracing spans ([Issue #3803](https://github.com/apollographql/router/issues/3803)), ([Issue #5172](https://github.com/apollographql/router/issues/5172)) -Add support for a new trace ID selector kind, the `apollo` trace ID, which represents the trace ID on [Apollo GraphOS Studio](https://studio.apollographql.com/). +Add support for a new trace ID selector kind, the `apollo` trace ID, which represents the trace ID on [Apollo GraphOS Studio](https://studio.apollographql.com/). An example configuration using `trace_id: apollo`: @@ -99,7 +99,7 @@ telemetry: eq: - true - on_graphql_error: true -``` +``` By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/5221 @@ -204,7 +204,7 @@ telemetry: - "topProducts" ``` -Using the new instruments consumes significant performance resources from the router. Their performance will be improved in a future release. +Using the new instruments consumes significant performance resources from the router. Their performance will be improved in a future release. Large numbers of metrics may also be generated by using the instruments, so make sure to not incur excessively large APM costs. @@ -220,10 +220,10 @@ By [@BrynCooke](https://github.com/BrynCooke) in https://github.com/apollographq ### Support telemetry selectors with errors ([Issue #5027](https://github.com/apollographql/router/issues/5027)) -The router now supports telemetry selectors that take into account the occurrence of errors. This capability enables you to create metrics, events, or span attributes that contain error messages. +The router now supports telemetry selectors that take into account the occurrence of errors. This capability enables you to create metrics, events, or span attributes that contain error messages. For example, you can create a counter for the number of timed-out requests for subgraphs: - + ```yaml telemetry: @@ -323,7 +323,7 @@ By [@BrynCooke](https://github.com/BrynCooke) in https://github.com/apollographq The router's hashing algorithm has been updated to prevent cache collisions when the router's configuration changes. -> [!IMPORTANT] +> [!IMPORTANT] > If you have enabled [Distributed query plan caching](https://www.apollographql.com/docs/router/configuration/distributed-caching/#distributed-query-plan-caching), this release changes the hashing algorithm used for the cache keys. On account of this, you should anticipate additional cache regeneration cost when updating between these versions while the new hashing algorithm comes into service. The router supports multiple options that affect the generated query plans, including: @@ -338,7 +338,7 @@ If distributed query plan caching is enabled, changing any of these options resu This could be problematic in the following scenarios: 1. The router configuration changes and a query plan is loaded from cache which is incompatible with the new configuration. -2. Routers with different configurations share the same cache, which causes them to cache and load incompatible query plans. +2. Routers with different configurations share the same cache, which causes them to cache and load incompatible query plans. To prevent these from happening, the router now creates a hash for the entire query planner configuration and includes it in the cache key. @@ -346,14 +346,14 @@ By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/p ### 5xx internal server error responses returned as GraphQL structured errors ([PR #5159](https://github.com/apollographql/router/pull/5159)) -Previously, the router returned internal server errors (5xx class) as plaintext to clients. Now in this release, the router returns these 5xx errors as structured GraphQL (for example, `{"errors": [...]}`). +Previously, the router returned internal server errors (5xx class) as plaintext to clients. Now in this release, the router returns these 5xx errors as structured GraphQL (for example, `{"errors": [...]}`). Internal server errors are returned upon unexpected or unrecoverable disruptions to the GraphQL request lifecycle execution. When these occur, the underlying error messages are logged at an `ERROR` level to the router's logs. By [@BrynCooke](https://github.com/BrynCooke) in https://github.com/apollographql/router/pull/5159 ### Custom telemetry events not created when logging is disabled ([PR #5165](https://github.com/apollographql/router/pull/5165)) -The router has been fixed to not create custom telemetry events when the log level is set to `off`. +The router has been fixed to not create custom telemetry events when the log level is set to `off`. An example configuration with `level` set to `off` for a custom event: @@ -418,7 +418,7 @@ By [@kindermax](https://github.com/kindermax) in https://github.com/apollographq The router now supports caching responses marked with `private` scope. This caching currently works only on subgraph responses without any schema-level information. -For details about the caching behavior, see [PR #4855](https://github.com/apollographql/router/pull/4855) +For details about the caching behavior, see [PR #4855](https://github.com/apollographql/router/pull/4855) By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/4855 @@ -449,12 +449,12 @@ telemetry: on: request attributes: http.response.body.size: false - # Only log when the x-log-request header is `log` + # Only log when the x-log-request header is `log` condition: eq: - "log" - request_header: "x-log-request" - + supergraph: # Custom event configuration for supergraph service ... subgraph: @@ -467,7 +467,7 @@ By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router The router now supports a configuration to ignore header prefixes with the JWT plugin. Given that many application headers use the format of `Authorization: `, this option enables the router to process requests for specific schemes within the `Authorization` header while ignoring others. -For example, you can configure the router to process requests with `Authorization: Bearer ` defined while ignoring others such as `Authorization: Basic `: +For example, you can configure the router to process requests with `Authorization: Bearer ` defined while ignoring others such as `Authorization: Basic `: ```yaml title="router.yaml" authentication: @@ -491,10 +491,10 @@ An example configuration using `condition` in `attributes` and `on_graphql_error ```yaml telemetry: instrumentation: - spans: - router: - attributes: - otel.status_description: + spans: + router: + attributes: + otel.status_description: static: "there was an error" condition: any: @@ -547,7 +547,7 @@ By [@tninesling](https://github.com/tninesling) in https://github.com/apollograp ### Filter fetches added to batch during batch creation ([PR #5034](https://github.com/apollographql/router/pull/5034)) -Previously, the router didn't filter query hashes when creating batches. This could result in failed queries because the additional hashes could incorrectly make a query appear to be committed when it wasn't actually registered in a batch. +Previously, the router didn't filter query hashes when creating batches. This could result in failed queries because the additional hashes could incorrectly make a query appear to be committed when it wasn't actually registered in a batch. This release fixes this issue by filtering query hashes during batch creation. @@ -567,7 +567,7 @@ By [@garypen](https://github.com/garypen) in https://github.com/apollographql/ro ### Document traffic shaping default configuration ([PR #4953](https://github.com/apollographql/router/pull/4953)) -The documentation for [configuring traffic shaping](https://www.apollographql.com/docs/router/configuration/traffic-shaping#configuration) has been updated to clarify that it's enabled by default with preset values. This setting has been the default since PR [#3330](https://github.com/apollographql/router/pull/3330), which landed in [v1.23.0](https://github.com/apollographql/router/releases/tag/v1.23.0). +The documentation for [configuring traffic shaping](https://www.apollographql.com/docs/router/configuration/traffic-shaping#configuration) has been updated to clarify that it's enabled by default with preset values. This setting has been the default since PR [#3330](https://github.com/apollographql/router/pull/3330), which landed in [v1.23.0](https://github.com/apollographql/router/releases/tag/v1.23.0). By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/4953 @@ -602,7 +602,7 @@ By [@o0Ignition0o](https://github.com/o0Ignition0o) in https://github.com/apollo ### Use entire schema when hashing an introspection query ([Issue #5006](https://github.com/apollographql/router/issues/5006)) -Correct a _different_ hashing bug which impacted introspection queries which was also introduced in [v1.44.0](https://github.com/apollographql/router/pull/4883). This other hashing bug failed to account for introspection queries, resulting in introspection results being misaligned to the current schema. This issue only affects Routers that use [distributed query plan caching](https://www.apollographql.com/docs/router/configuration/distributed-caching/#distributed-query-plan-caching), enabled via the `supergraph.query_planning.cache.redis.urls` configuration property. +Correct a _different_ hashing bug which impacted introspection queries which was also introduced in [v1.44.0](https://github.com/apollographql/router/pull/4883). This other hashing bug failed to account for introspection queries, resulting in introspection results being misaligned to the current schema. This issue only affects Routers that use [distributed query plan caching](https://www.apollographql.com/docs/router/configuration/distributed-caching/#distributed-query-plan-caching), enabled via the `supergraph.query_planning.cache.redis.urls` configuration property. This release fixes the hashing mechanism by adding the schema string to hashed data if an introspection field is encountered. As a result, the entire schema is taken into account and the correct introspection result is returned. @@ -625,7 +625,7 @@ By [@garypen](https://github.com/garypen) in https://github.com/apollographql/ro ### Query validation process with Rust ([PR #4551](https://github.com/apollographql/router/pull/4551)) -The router has been updated with a new Rust-based query validation process using `apollo-compiler` from the `apollo-rs` project. It replaces the Javascript implementation in the query planner. It improves query planner performance by moving the validation out of the query planner and into the router service, which frees up space in the query planner cache. +The router has been updated with a new Rust-based query validation process using `apollo-compiler` from the `apollo-rs` project. It replaces the Javascript implementation in the query planner. It improves query planner performance by moving the validation out of the query planner and into the router service, which frees up space in the query planner cache. Because validation now happens earlier in the router service and not in the query planner, error paths in the query planner are no longer encountered. Some messages in error responses returned from invalid queries should now be more clear. @@ -961,7 +961,7 @@ warning: unused import: `common::ValueExt` | ^^^^^^^^^^^^^^^^ ``` -That issue is now resolved. +That issue is now resolved. By [@garypen](https://github.com/garypen) in https://github.com/apollographql/router/pull/4919 From a2951a0d088968e77ece05f4e0cfbf2999aac007 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e?= Date: Wed, 5 Jun 2024 15:07:52 +0200 Subject: [PATCH 4/9] chore(deps): update apollo-compiler to v1.0.0-beta.17 (#5347) --- Cargo.lock | 12 ++++++------ Cargo.toml | 2 +- examples/supergraph-sdl/rust/Cargo.toml | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 17e6a28d16..a3e1b616f4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -192,9 +192,9 @@ checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1" [[package]] name = "apollo-compiler" -version = "1.0.0-beta.16" +version = "1.0.0-beta.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175659cea0232b38bfacd1505aed00221cc4028d848699ce9e3422c6bf87d90a" +checksum = "a46c3a5e9a23a39089af6bada6fe0976369458434095bd9c26ce94c56f219842" dependencies = [ "apollo-parser", "ariadne", @@ -501,9 +501,9 @@ checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" [[package]] name = "ariadne" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd002a6223f12c7a95cdd4b1cb3a0149d22d37f7a9ecdb2cb691a071fe236c29" +checksum = "44055e597c674aef7cb903b2b9f6e4cba1277ed0d2d61dae7cd52d7ffa81f8e2" dependencies = [ "concolor", "unicode-width", @@ -8227,9 +8227,9 @@ dependencies = [ [[package]] name = "yansi" -version = "0.5.1" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "zerocopy" diff --git a/Cargo.toml b/Cargo.toml index 134d321297..26bbc24bfd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,7 +48,7 @@ debug = 1 # Dependencies used in more than one place are specified here in order to keep versions in sync: # https://doc.rust-lang.org/cargo/reference/workspaces.html#the-dependencies-table [workspace.dependencies] -apollo-compiler = "=1.0.0-beta.16" +apollo-compiler = "=1.0.0-beta.17" apollo-parser = "0.7.6" apollo-smith = { version = "0.5.0", features = ["parser-impl"] } async-trait = "0.1.77" diff --git a/examples/supergraph-sdl/rust/Cargo.toml b/examples/supergraph-sdl/rust/Cargo.toml index 9bf12b0972..0ca8039c8d 100644 --- a/examples/supergraph-sdl/rust/Cargo.toml +++ b/examples/supergraph-sdl/rust/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] anyhow = "1" -apollo-compiler = "=1.0.0-beta.16" +apollo-compiler = "=1.0.0-beta.17" apollo-router = { path = "../../../apollo-router" } async-trait = "0.1" tower = { version = "0.4", features = ["full"] } From 2c13904b3a49d265ec567f34aa837ab7b9a757bc Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 5 Jun 2024 21:16:09 +0300 Subject: [PATCH 5/9] Add CHANGELOG for https://github.com/apollographql/router/pull/5347 --- .../fix_skewer_boyfriend_forum_sleigh.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .changesets/fix_skewer_boyfriend_forum_sleigh.md diff --git a/.changesets/fix_skewer_boyfriend_forum_sleigh.md b/.changesets/fix_skewer_boyfriend_forum_sleigh.md new file mode 100644 index 0000000000..1a45be957a --- /dev/null +++ b/.changesets/fix_skewer_boyfriend_forum_sleigh.md @@ -0,0 +1,18 @@ +### Update `apollo-compiler` for two small improvements ([PR #5347](https://github.com/apollographql/router/pull/5347)) + +Updated our underlying `apollo-rs` dependency on our `apollo-compiler` crate to bring in two nice improvements: + +- **Fix validation performance bug + + Adds a cache in fragment spread validation, fixing a situation where validating a query + with many fragment spreads against a schema with many interfaces could take multiple + seconds to validate. + +- **Remove ariadne byte/char mapping + + Generating JSON or CLI reports for apollo-compiler diagnostics used a translation layer + between byte offsets and character offsets, which cost some computation and memory + proportional to the size of the source text. The latest version of `ariadne` allows us to + remove this translation. + +By [@goto-bus-stop](https://github.com/goto-bus-stop) in https://github.com/apollographql/router/pull/5347 \ No newline at end of file From a7c43ec4a6d6e9a751d9f3fa017fad1e58ba4a60 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 5 Jun 2024 21:42:12 +0300 Subject: [PATCH 6/9] prep release: v1.48.1-rc.0 --- Cargo.lock | 8 +- apollo-federation/Cargo.toml | 2 +- apollo-router-benchmarks/Cargo.toml | 2 +- apollo-router-scaffold/Cargo.toml | 2 +- .../templates/base/Cargo.toml | 2 +- .../templates/base/xtask/Cargo.toml | 2 +- apollo-router/Cargo.toml | 4 +- .../tracing/docker-compose.datadog.yml | 2 +- dockerfiles/tracing/docker-compose.jaeger.yml | 2 +- dockerfiles/tracing/docker-compose.zipkin.yml | 2 +- helm/chart/router/Chart.yaml | 4 +- helm/chart/router/README.md | 8 +- licenses.html | 217 +++++++++++++++++- scripts/install.sh | 2 +- 14 files changed, 235 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a3e1b616f4..83725f5370 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -220,7 +220,7 @@ dependencies = [ [[package]] name = "apollo-federation" -version = "1.48.0" +version = "1.48.1-rc.0" dependencies = [ "apollo-compiler", "derive_more", @@ -262,7 +262,7 @@ dependencies = [ [[package]] name = "apollo-router" -version = "1.48.0" +version = "1.48.1-rc.0" dependencies = [ "access-json", "anyhow", @@ -425,7 +425,7 @@ dependencies = [ [[package]] name = "apollo-router-benchmarks" -version = "1.48.0" +version = "1.48.1-rc.0" dependencies = [ "apollo-parser", "apollo-router", @@ -441,7 +441,7 @@ dependencies = [ [[package]] name = "apollo-router-scaffold" -version = "1.48.0" +version = "1.48.1-rc.0" dependencies = [ "anyhow", "cargo-scaffold", diff --git a/apollo-federation/Cargo.toml b/apollo-federation/Cargo.toml index 8b5680694d..009e1d1ba6 100644 --- a/apollo-federation/Cargo.toml +++ b/apollo-federation/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-federation" -version = "1.48.0" +version = "1.48.1-rc.0" authors = ["The Apollo GraphQL Contributors"] edition = "2021" description = "Apollo Federation" diff --git a/apollo-router-benchmarks/Cargo.toml b/apollo-router-benchmarks/Cargo.toml index 6bd5ca1fd5..29c4ebdee5 100644 --- a/apollo-router-benchmarks/Cargo.toml +++ b/apollo-router-benchmarks/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router-benchmarks" -version = "1.48.0" +version = "1.48.1-rc.0" authors = ["Apollo Graph, Inc. "] edition = "2021" license = "Elastic-2.0" diff --git a/apollo-router-scaffold/Cargo.toml b/apollo-router-scaffold/Cargo.toml index 289c06fc2e..a35f546241 100644 --- a/apollo-router-scaffold/Cargo.toml +++ b/apollo-router-scaffold/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router-scaffold" -version = "1.48.0" +version = "1.48.1-rc.0" authors = ["Apollo Graph, Inc. "] edition = "2021" license = "Elastic-2.0" diff --git a/apollo-router-scaffold/templates/base/Cargo.toml b/apollo-router-scaffold/templates/base/Cargo.toml index 054b77f5bf..20170acea3 100644 --- a/apollo-router-scaffold/templates/base/Cargo.toml +++ b/apollo-router-scaffold/templates/base/Cargo.toml @@ -22,7 +22,7 @@ apollo-router = { path ="{{integration_test}}apollo-router" } apollo-router = { git="https://github.com/apollographql/router.git", branch="{{branch}}" } {{else}} # Note if you update these dependencies then also update xtask/Cargo.toml -apollo-router = "1.48.0" +apollo-router = "1.48.1-rc.0" {{/if}} {{/if}} async-trait = "0.1.52" diff --git a/apollo-router-scaffold/templates/base/xtask/Cargo.toml b/apollo-router-scaffold/templates/base/xtask/Cargo.toml index b8225d2ea8..89beb252d6 100644 --- a/apollo-router-scaffold/templates/base/xtask/Cargo.toml +++ b/apollo-router-scaffold/templates/base/xtask/Cargo.toml @@ -13,7 +13,7 @@ apollo-router-scaffold = { path ="{{integration_test}}apollo-router-scaffold" } {{#if branch}} apollo-router-scaffold = { git="https://github.com/apollographql/router.git", branch="{{branch}}" } {{else}} -apollo-router-scaffold = { git = "https://github.com/apollographql/router.git", tag = "v1.48.0" } +apollo-router-scaffold = { git = "https://github.com/apollographql/router.git", tag = "v1.48.1-rc.0" } {{/if}} {{/if}} anyhow = "1.0.58" diff --git a/apollo-router/Cargo.toml b/apollo-router/Cargo.toml index c129c3ef37..63eca16031 100644 --- a/apollo-router/Cargo.toml +++ b/apollo-router/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router" -version = "1.48.0" +version = "1.48.1-rc.0" authors = ["Apollo Graph, Inc. "] repository = "https://github.com/apollographql/router/" documentation = "https://docs.rs/apollo-router" @@ -68,7 +68,7 @@ askama = "0.12.1" access-json = "0.1.0" anyhow = "1.0.80" apollo-compiler.workspace = true -apollo-federation = { path = "../apollo-federation", version = "=1.48.0"} +apollo-federation = { path = "../apollo-federation", version = "=1.48.1-rc.0" } arc-swap = "1.6.0" async-channel = "1.9.0" async-compression = { version = "0.4.6", features = [ diff --git a/dockerfiles/tracing/docker-compose.datadog.yml b/dockerfiles/tracing/docker-compose.datadog.yml index 64047bf2d6..b8e40a04c5 100644 --- a/dockerfiles/tracing/docker-compose.datadog.yml +++ b/dockerfiles/tracing/docker-compose.datadog.yml @@ -3,7 +3,7 @@ services: apollo-router: container_name: apollo-router - image: ghcr.io/apollographql/router:v1.48.0 + image: ghcr.io/apollographql/router:v1.48.1-rc.0 volumes: - ./supergraph.graphql:/etc/config/supergraph.graphql - ./router/datadog.router.yaml:/etc/config/configuration.yaml diff --git a/dockerfiles/tracing/docker-compose.jaeger.yml b/dockerfiles/tracing/docker-compose.jaeger.yml index 11b98eb021..d6c26bb1e1 100644 --- a/dockerfiles/tracing/docker-compose.jaeger.yml +++ b/dockerfiles/tracing/docker-compose.jaeger.yml @@ -4,7 +4,7 @@ services: apollo-router: container_name: apollo-router #build: ./router - image: ghcr.io/apollographql/router:v1.48.0 + image: ghcr.io/apollographql/router:v1.48.1-rc.0 volumes: - ./supergraph.graphql:/etc/config/supergraph.graphql - ./router/jaeger.router.yaml:/etc/config/configuration.yaml diff --git a/dockerfiles/tracing/docker-compose.zipkin.yml b/dockerfiles/tracing/docker-compose.zipkin.yml index a0f0c530b7..9ef4540a07 100644 --- a/dockerfiles/tracing/docker-compose.zipkin.yml +++ b/dockerfiles/tracing/docker-compose.zipkin.yml @@ -4,7 +4,7 @@ services: apollo-router: container_name: apollo-router build: ./router - image: ghcr.io/apollographql/router:v1.48.0 + image: ghcr.io/apollographql/router:v1.48.1-rc.0 volumes: - ./supergraph.graphql:/etc/config/supergraph.graphql - ./router/zipkin.router.yaml:/etc/config/configuration.yaml diff --git a/helm/chart/router/Chart.yaml b/helm/chart/router/Chart.yaml index 1774ed688d..284f7a67d1 100644 --- a/helm/chart/router/Chart.yaml +++ b/helm/chart/router/Chart.yaml @@ -20,10 +20,10 @@ type: application # so it matches the shape of our release process and release automation. # By proxy of that decision, this version uses SemVer 2.0.0, though the prefix # of "v" is not included. -version: 1.48.0 +version: 1.48.1-rc.0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: "v1.48.0" +appVersion: "v1.48.1-rc.0" diff --git a/helm/chart/router/README.md b/helm/chart/router/README.md index 8f415c7ac9..6b5a587184 100644 --- a/helm/chart/router/README.md +++ b/helm/chart/router/README.md @@ -2,7 +2,7 @@ [router](https://github.com/apollographql/router) Rust Graph Routing runtime for Apollo Federation -![Version: 1.48.0](https://img.shields.io/badge/Version-1.48.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.48.0](https://img.shields.io/badge/AppVersion-v1.48.0-informational?style=flat-square) +![Version: 1.48.1-rc.0](https://img.shields.io/badge/Version-1.48.1--rc.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.48.1-rc.0](https://img.shields.io/badge/AppVersion-v1.48.1--rc.0-informational?style=flat-square) ## Prerequisites @@ -11,7 +11,7 @@ ## Get Repo Info ```console -helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.48.0 +helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.48.1-rc.0 ``` ## Install Chart @@ -19,7 +19,7 @@ helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.48.0 **Important:** only helm3 is supported ```console -helm upgrade --install [RELEASE_NAME] oci://ghcr.io/apollographql/helm-charts/router --version 1.48.0 --values my-values.yaml +helm upgrade --install [RELEASE_NAME] oci://ghcr.io/apollographql/helm-charts/router --version 1.48.1-rc.0 --values my-values.yaml ``` _See [configuration](#configuration) below._ @@ -95,4 +95,4 @@ helm show values oci://ghcr.io/apollographql/helm-charts/router | virtualservice.enabled | bool | `false` | | ---------------------------------------------- -Autogenerated from chart metadata using [helm-docs v1.11.0](https://github.com/norwoodj/helm-docs/releases/v1.11.0) +Autogenerated from chart metadata using [helm-docs v1.13.1](https://github.com/norwoodj/helm-docs/releases/v1.13.1) diff --git a/licenses.html b/licenses.html index 58c0e2eae0..d2aea988ab 100644 --- a/licenses.html +++ b/licenses.html @@ -48,8 +48,8 @@

Overview of licenses:

  • MIT License (152)
  • BSD 3-Clause "New" or "Revised" License (12)
  • ISC License (11)
  • +
  • Elastic License 2.0 (6)
  • BSD 2-Clause "Simplified" License (3)
  • -
  • Elastic License 2.0 (3)
  • Mozilla Public License 2.0 (3)
  • Creative Commons Zero v1.0 Universal (2)
  • OpenSSL License (2)
  • @@ -6097,6 +6097,215 @@

    Used by:

    Copyright 2016 Sean McArthur +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + + +
  • +

    Apache License 2.0

    +

    Used by:

    + +
                                  Apache License
    +                        Version 2.0, January 2004
    +                     http://www.apache.org/licenses/
    +
    +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
    +
    +1. Definitions.
    +
    +   "License" shall mean the terms and conditions for use, reproduction,
    +   and distribution as defined by Sections 1 through 9 of this document.
    +
    +   "Licensor" shall mean the copyright owner or entity authorized by
    +   the copyright owner that is granting the License.
    +
    +   "Legal Entity" shall mean the union of the acting entity and all
    +   other entities that control, are controlled by, or are under common
    +   control with that entity. For the purposes of this definition,
    +   "control" means (i) the power, direct or indirect, to cause the
    +   direction or management of such entity, whether by contract or
    +   otherwise, or (ii) ownership of fifty percent (50%) or more of the
    +   outstanding shares, or (iii) beneficial ownership of such entity.
    +
    +   "You" (or "Your") shall mean an individual or Legal Entity
    +   exercising permissions granted by this License.
    +
    +   "Source" form shall mean the preferred form for making modifications,
    +   including but not limited to software source code, documentation
    +   source, and configuration files.
    +
    +   "Object" form shall mean any form resulting from mechanical
    +   transformation or translation of a Source form, including but
    +   not limited to compiled object code, generated documentation,
    +   and conversions to other media types.
    +
    +   "Work" shall mean the work of authorship, whether in Source or
    +   Object form, made available under the License, as indicated by a
    +   copyright notice that is included in or attached to the work
    +   (an example is provided in the Appendix below).
    +
    +   "Derivative Works" shall mean any work, whether in Source or Object
    +   form, that is based on (or derived from) the Work and for which the
    +   editorial revisions, annotations, elaborations, or other modifications
    +   represent, as a whole, an original work of authorship. For the purposes
    +   of this License, Derivative Works shall not include works that remain
    +   separable from, or merely link (or bind by name) to the interfaces of,
    +   the Work and Derivative Works thereof.
    +
    +   "Contribution" shall mean any work of authorship, including
    +   the original version of the Work and any modifications or additions
    +   to that Work or Derivative Works thereof, that is intentionally
    +   submitted to Licensor for inclusion in the Work by the copyright owner
    +   or by an individual or Legal Entity authorized to submit on behalf of
    +   the copyright owner. For the purposes of this definition, "submitted"
    +   means any form of electronic, verbal, or written communication sent
    +   to the Licensor or its representatives, including but not limited to
    +   communication on electronic mailing lists, source code control systems,
    +   and issue tracking systems that are managed by, or on behalf of, the
    +   Licensor for the purpose of discussing and improving the Work, but
    +   excluding communication that is conspicuously marked or otherwise
    +   designated in writing by the copyright owner as "Not a Contribution."
    +
    +   "Contributor" shall mean Licensor and any individual or Legal Entity
    +   on behalf of whom a Contribution has been received by Licensor and
    +   subsequently incorporated within the Work.
    +
    +2. Grant of Copyright License. Subject to the terms and conditions of
    +   this License, each Contributor hereby grants to You a perpetual,
    +   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
    +   copyright license to reproduce, prepare Derivative Works of,
    +   publicly display, publicly perform, sublicense, and distribute the
    +   Work and such Derivative Works in Source or Object form.
    +
    +3. Grant of Patent License. Subject to the terms and conditions of
    +   this License, each Contributor hereby grants to You a perpetual,
    +   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
    +   (except as stated in this section) patent license to make, have made,
    +   use, offer to sell, sell, import, and otherwise transfer the Work,
    +   where such license applies only to those patent claims licensable
    +   by such Contributor that are necessarily infringed by their
    +   Contribution(s) alone or by combination of their Contribution(s)
    +   with the Work to which such Contribution(s) was submitted. If You
    +   institute patent litigation against any entity (including a
    +   cross-claim or counterclaim in a lawsuit) alleging that the Work
    +   or a Contribution incorporated within the Work constitutes direct
    +   or contributory patent infringement, then any patent licenses
    +   granted to You under this License for that Work shall terminate
    +   as of the date such litigation is filed.
    +
    +4. Redistribution. You may reproduce and distribute copies of the
    +   Work or Derivative Works thereof in any medium, with or without
    +   modifications, and in Source or Object form, provided that You
    +   meet the following conditions:
    +
    +   (a) You must give any other recipients of the Work or
    +       Derivative Works a copy of this License; and
    +
    +   (b) You must cause any modified files to carry prominent notices
    +       stating that You changed the files; and
    +
    +   (c) You must retain, in the Source form of any Derivative Works
    +       that You distribute, all copyright, patent, trademark, and
    +       attribution notices from the Source form of the Work,
    +       excluding those notices that do not pertain to any part of
    +       the Derivative Works; and
    +
    +   (d) If the Work includes a "NOTICE" text file as part of its
    +       distribution, then any Derivative Works that You distribute must
    +       include a readable copy of the attribution notices contained
    +       within such NOTICE file, excluding those notices that do not
    +       pertain to any part of the Derivative Works, in at least one
    +       of the following places: within a NOTICE text file distributed
    +       as part of the Derivative Works; within the Source form or
    +       documentation, if provided along with the Derivative Works; or,
    +       within a display generated by the Derivative Works, if and
    +       wherever such third-party notices normally appear. The contents
    +       of the NOTICE file are for informational purposes only and
    +       do not modify the License. You may add Your own attribution
    +       notices within Derivative Works that You distribute, alongside
    +       or as an addendum to the NOTICE text from the Work, provided
    +       that such additional attribution notices cannot be construed
    +       as modifying the License.
    +
    +   You may add Your own copyright statement to Your modifications and
    +   may provide additional or different license terms and conditions
    +   for use, reproduction, or distribution of Your modifications, or
    +   for any such Derivative Works as a whole, provided Your use,
    +   reproduction, and distribution of the Work otherwise complies with
    +   the conditions stated in this License.
    +
    +5. Submission of Contributions. Unless You explicitly state otherwise,
    +   any Contribution intentionally submitted for inclusion in the Work
    +   by You to the Licensor shall be under the terms and conditions of
    +   this License, without any additional terms or conditions.
    +   Notwithstanding the above, nothing herein shall supersede or modify
    +   the terms of any separate license agreement you may have executed
    +   with Licensor regarding such Contributions.
    +
    +6. Trademarks. This License does not grant permission to use the trade
    +   names, trademarks, service marks, or product names of the Licensor,
    +   except as required for reasonable and customary use in describing the
    +   origin of the Work and reproducing the content of the NOTICE file.
    +
    +7. Disclaimer of Warranty. Unless required by applicable law or
    +   agreed to in writing, Licensor provides the Work (and each
    +   Contributor provides its Contributions) on an "AS IS" BASIS,
    +   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
    +   implied, including, without limitation, any warranties or conditions
    +   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
    +   PARTICULAR PURPOSE. You are solely responsible for determining the
    +   appropriateness of using or redistributing the Work and assume any
    +   risks associated with Your exercise of permissions under this License.
    +
    +8. Limitation of Liability. In no event and under no legal theory,
    +   whether in tort (including negligence), contract, or otherwise,
    +   unless required by applicable law (such as deliberate and grossly
    +   negligent acts) or agreed to in writing, shall any Contributor be
    +   liable to You for damages, including any direct, indirect, special,
    +   incidental, or consequential damages of any character arising as a
    +   result of this License or out of the use or inability to use the
    +   Work (including but not limited to damages for loss of goodwill,
    +   work stoppage, computer failure or malfunction, or any and all
    +   other commercial damages or losses), even if such Contributor
    +   has been advised of the possibility of such damages.
    +
    +9. Accepting Warranty or Additional Liability. While redistributing
    +   the Work or Derivative Works thereof, You may choose to offer,
    +   and charge a fee for, acceptance of support, warranty, indemnity,
    +   or other liability obligations and/or rights consistent with this
    +   License. However, in accepting such obligations, You may act only
    +   on Your own behalf and on Your sole responsibility, not on behalf
    +   of any other Contributor, and only if You agree to indemnify,
    +   defend, and hold each Contributor harmless for any liability
    +   incurred by, or claims asserted against, such Contributor by reason
    +   of your accepting any such warranty or additional liability.
    +
    +END OF TERMS AND CONDITIONS
    +
    +APPENDIX: How to apply the Apache License to your work.
    +
    +   To apply the Apache License to your work, attach the following
    +   boilerplate notice, with the fields enclosed by brackets "[]"
    +   replaced with your own identifying information. (Don't include
    +   the brackets!)  The text should be enclosed in the appropriate
    +   comment syntax for the file format. We also recommend that a
    +   file or class name and description of purpose be included on the
    +   same "printed page" as the copyright notice for easier
    +   identification within third-party archives.
    +
    +Copyright 2017 Sergio Benitez
    +
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
    @@ -8393,7 +8602,6 @@ 

    Used by:

  • wiremock
  • xmlparser
  • yaml-rust
  • -
  • yansi
  •                               Apache License
                             Version 2.0, January 2004
    @@ -11536,7 +11744,6 @@ 

    Used by:

    Apache License 2.0

    Used by:

      -
    • apollo-compiler
    • apollo-encoder
    • apollo-parser
    • apollo-smith
    • @@ -12190,6 +12397,7 @@

      Used by:

      Apache License 2.0

      Used by:

        +
      • apollo-compiler
      • curve25519-dalek-derive
      • deadpool-runtime
      • deno-proc-macro-rules
      • @@ -13163,6 +13371,9 @@

        Elastic License 2.0

        Used by:

        Copyright 2021 Apollo Graph, Inc.
         
        diff --git a/scripts/install.sh b/scripts/install.sh
        index c031121259..8353a59187 100755
        --- a/scripts/install.sh
        +++ b/scripts/install.sh
        @@ -11,7 +11,7 @@ BINARY_DOWNLOAD_PREFIX="https://github.com/apollographql/router/releases/downloa
         
         # Router version defined in apollo-router's Cargo.toml
         # Note: Change this line manually during the release steps.
        -PACKAGE_VERSION="v1.48.0"
        +PACKAGE_VERSION="v1.48.1-rc.0"
         
         download_binary() {
             downloader --check
        
        From e5c0e5242172f6bfd2673f61ac4c3030732191d9 Mon Sep 17 00:00:00 2001
        From: Ivan Goncharov 
        Date: Thu, 6 Jun 2024 18:20:28 +0300
        Subject: [PATCH 7/9] improvement: error message for invalid 'content-type' in
         subgraph response (#5223)
        
        Co-authored-by: Coenen Benjamin 
        Co-authored-by: Jesse Rosenberger 
        ---
         .changesets/fix_fix_content_type_error.md     |  13 ++
         .../src/services/subgraph_service.rs          | 175 ++++++++++++++----
         2 files changed, 157 insertions(+), 31 deletions(-)
         create mode 100644 .changesets/fix_fix_content_type_error.md
        
        diff --git a/.changesets/fix_fix_content_type_error.md b/.changesets/fix_fix_content_type_error.md
        new file mode 100644
        index 0000000000..0d182ded44
        --- /dev/null
        +++ b/.changesets/fix_fix_content_type_error.md
        @@ -0,0 +1,13 @@
        +### Improve error message produced when subgraphs responses don't include an expected `content-type` header value ([Issue #5359](https://github.com/apollographql/router/issues/5359))
        +
        +To improve a common debuggability challenge when a subgraph response doesn't contain an expected `content-type` header value, the error message produced will include additional details about the error.
        +
        +Examples:
        +
        +   * ```
        +     HTTP fetch failed from 'test': subgraph response contains invalid 'content-type' header value \"application/json,application/json\"; expected content-type: application/json or content-type: application/graphql-response+json
        +      ```
        +   * ```
        +     HTTP fetch failed from 'test': subgraph response does not contain 'content-type' header; expected content-type: application/json or content-type: application/graphql-response+json
        +      ```
        +By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/5223
        \ No newline at end of file
        diff --git a/apollo-router/src/services/subgraph_service.rs b/apollo-router/src/services/subgraph_service.rs
        index 3e484603fe..99e3ed44c5 100644
        --- a/apollo-router/src/services/subgraph_service.rs
        +++ b/apollo-router/src/services/subgraph_service.rs
        @@ -1294,37 +1294,45 @@ enum ContentType {
         }
         
         fn get_graphql_content_type(service_name: &str, parts: &Parts) -> Result {
        -    let content_type = parts
        -        .headers
        -        .get(header::CONTENT_TYPE)
        -        .map(|v| v.to_str().map(MediaType::parse));
        -    match content_type {
        -        Some(Ok(Ok(content_type))) => {
        -            if content_type.ty == APPLICATION && content_type.subty == JSON {
        +    if let Some(raw_content_type) = parts.headers.get(header::CONTENT_TYPE) {
        +        let content_type = raw_content_type
        +            .to_str()
        +            .ok()
        +            .and_then(|str| MediaType::parse(str).ok());
        +
        +        match content_type {
        +            Some(mime) if mime.ty == APPLICATION && mime.subty == JSON => {
                         Ok(ContentType::ApplicationJson)
        -            } else if content_type.ty == APPLICATION
        -                && content_type.subty == GRAPHQL_RESPONSE
        -                && content_type.suffix == Some(JSON)
        +            }
        +            Some(mime)
        +                if mime.ty == APPLICATION
        +                    && mime.subty == GRAPHQL_RESPONSE
        +                    && mime.suffix == Some(JSON) =>
                     {
                         Ok(ContentType::ApplicationGraphqlResponseJson)
        -            } else {
        -                Err(FetchError::SubrequestHttpError {
        -                    status_code: Some(parts.status.as_u16()),
        -                    service: service_name.to_string(),
        -                    reason: format!("subgraph didn't return JSON (expected content-type: {} or content-type: {}; found content-type: {content_type})", APPLICATION_JSON.essence_str(), GRAPHQL_JSON_RESPONSE_HEADER_VALUE),
        -                })
                     }
        +            Some(mime) => Err(format!(
        +                "subgraph response contains unsupported content-type: {}",
        +                mime,
        +            )),
        +            None => Err(format!(
        +                "subgraph response contains invalid 'content-type' header value {:?}",
        +                raw_content_type,
        +            )),
                 }
        -        None | Some(_) => Err(FetchError::SubrequestHttpError {
        -            status_code: Some(parts.status.as_u16()),
        -            service: service_name.to_string(),
        -            reason: format!(
        -                "subgraph didn't return JSON (expected content-type: {} or content-type: {})",
        -                APPLICATION_JSON.essence_str(),
        -                GRAPHQL_JSON_RESPONSE_HEADER_VALUE
        -            ),
        -        }),
        -    }
        +    } else {
        +        Err("subgraph response does not contain 'content-type' header".to_owned())
        +    }
        +    .map_err(|reason| FetchError::SubrequestHttpError {
        +        status_code: Some(parts.status.as_u16()),
        +        service: service_name.to_string(),
        +        reason: format!(
        +            "{}; expected content-type: {} or content-type: {}",
        +            reason,
        +            APPLICATION_JSON.essence_str(),
        +            GRAPHQL_JSON_RESPONSE_HEADER_VALUE
        +        ),
        +    })
         }
         
         async fn do_fetch(
        @@ -1698,8 +1706,37 @@ mod tests {
                 server.await.unwrap();
             }
         
        -    // starts a local server emulating a subgraph returning bad response format
        -    async fn emulate_subgraph_bad_response_format(listener: TcpListener) {
        +    // starts a local server emulating a subgraph returning response with missing content_type
        +    async fn emulate_subgraph_missing_content_type(listener: TcpListener) {
        +        async fn handle(_request: http::Request) -> Result, Infallible> {
        +            Ok(http::Response::builder()
        +                .status(StatusCode::OK)
        +                .body(r#"TEST"#.into())
        +                .unwrap())
        +        }
        +
        +        let make_svc = make_service_fn(|_conn| async { Ok::<_, Infallible>(service_fn(handle)) });
        +        let server = Server::from_tcp(listener).unwrap().serve(make_svc);
        +        server.await.unwrap();
        +    }
        +
        +    // starts a local server emulating a subgraph returning response with invalid content_type
        +    async fn emulate_subgraph_invalid_content_type(listener: TcpListener) {
        +        async fn handle(_request: http::Request) -> Result, Infallible> {
        +            Ok(http::Response::builder()
        +                .header(CONTENT_TYPE, "application/json,application/json")
        +                .status(StatusCode::OK)
        +                .body(r#"TEST"#.into())
        +                .unwrap())
        +        }
        +
        +        let make_svc = make_service_fn(|_conn| async { Ok::<_, Infallible>(service_fn(handle)) });
        +        let server = Server::from_tcp(listener).unwrap().serve(make_svc);
        +        server.await.unwrap();
        +    }
        +
        +    // starts a local server emulating a subgraph returning unsupported content_type
        +    async fn emulate_subgraph_unsupported_content_type(listener: TcpListener) {
                 async fn handle(_request: http::Request) -> Result, Infallible> {
                     Ok(http::Response::builder()
                         .header(CONTENT_TYPE, "text/html")
        @@ -2568,10 +2605,86 @@ mod tests {
             }
         
             #[tokio::test(flavor = "multi_thread")]
        -    async fn test_bad_content_type() {
        +    async fn test_missing_content_type() {
        +        let listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
        +        let socket_addr = listener.local_addr().unwrap();
        +        tokio::task::spawn(emulate_subgraph_missing_content_type(listener));
        +
        +        let subgraph_service = SubgraphService::new(
        +            "test",
        +            true,
        +            None,
        +            Notify::default(),
        +            HttpClientServiceFactory::from_config(
        +                "test",
        +                &Configuration::default(),
        +                Http2Config::Enable,
        +            ),
        +        )
        +        .expect("can create a SubgraphService");
        +
        +        let url = Uri::from_str(&format!("http://{socket_addr}")).unwrap();
        +        let response = subgraph_service
        +            .oneshot(
        +                SubgraphRequest::builder()
        +                    .supergraph_request(supergraph_request("query"))
        +                    .subgraph_request(subgraph_http_request(url, "query"))
        +                    .operation_kind(OperationKind::Query)
        +                    .subgraph_name(String::from("test"))
        +                    .context(Context::new())
        +                    .build(),
        +            )
        +            .await
        +            .unwrap();
        +        assert_eq!(
        +            response.response.body().errors[0].message,
        +            "HTTP fetch failed from 'test': subgraph response does not contain 'content-type' header; expected content-type: application/json or content-type: application/graphql-response+json"
        +        );
        +    }
        +
        +    #[tokio::test(flavor = "multi_thread")]
        +    async fn test_invalid_content_type() {
        +        let listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
        +        let socket_addr = listener.local_addr().unwrap();
        +        tokio::task::spawn(emulate_subgraph_invalid_content_type(listener));
        +
        +        let subgraph_service = SubgraphService::new(
        +            "test",
        +            true,
        +            None,
        +            Notify::default(),
        +            HttpClientServiceFactory::from_config(
        +                "test",
        +                &Configuration::default(),
        +                Http2Config::Enable,
        +            ),
        +        )
        +        .expect("can create a SubgraphService");
        +
        +        let url = Uri::from_str(&format!("http://{socket_addr}")).unwrap();
        +        let response = subgraph_service
        +            .oneshot(
        +                SubgraphRequest::builder()
        +                    .supergraph_request(supergraph_request("query"))
        +                    .subgraph_request(subgraph_http_request(url, "query"))
        +                    .operation_kind(OperationKind::Query)
        +                    .subgraph_name(String::from("test"))
        +                    .context(Context::new())
        +                    .build(),
        +            )
        +            .await
        +            .unwrap();
        +        assert_eq!(
        +            response.response.body().errors[0].message,
        +            "HTTP fetch failed from 'test': subgraph response contains invalid 'content-type' header value \"application/json,application/json\"; expected content-type: application/json or content-type: application/graphql-response+json"
        +        );
        +    }
        +
        +    #[tokio::test(flavor = "multi_thread")]
        +    async fn test_unsupported_content_type() {
                 let listener = std::net::TcpListener::bind("127.0.0.1:0").unwrap();
                 let socket_addr = listener.local_addr().unwrap();
        -        tokio::task::spawn(emulate_subgraph_bad_response_format(listener));
        +        tokio::task::spawn(emulate_subgraph_unsupported_content_type(listener));
         
                 let subgraph_service = SubgraphService::new(
                     "test",
        @@ -2601,7 +2714,7 @@ mod tests {
                     .unwrap();
                 assert_eq!(
                     response.response.body().errors[0].message,
        -            "HTTP fetch failed from 'test': subgraph didn't return JSON (expected content-type: application/json or content-type: application/graphql-response+json; found content-type: text/html)"
        +            "HTTP fetch failed from 'test': subgraph response contains unsupported content-type: text/html; expected content-type: application/json or content-type: application/graphql-response+json"
                 );
             }
         
        
        From 993ab9f6d3c6ae3bf93a26bee4c765a5d978f583 Mon Sep 17 00:00:00 2001
        From: Jesse Rosenberger 
        Date: Mon, 10 Jun 2024 14:44:46 +0300
        Subject: [PATCH 8/9] Apply suggestions from code review
        MIME-Version: 1.0
        Content-Type: text/plain; charset=UTF-8
        Content-Transfer-Encoding: 8bit
        
        Co-authored-by: RenΓ©e 
        ---
         .changesets/fix_skewer_boyfriend_forum_sleigh.md | 4 ++--
         1 file changed, 2 insertions(+), 2 deletions(-)
        
        diff --git a/.changesets/fix_skewer_boyfriend_forum_sleigh.md b/.changesets/fix_skewer_boyfriend_forum_sleigh.md
        index 1a45be957a..992393b27b 100644
        --- a/.changesets/fix_skewer_boyfriend_forum_sleigh.md
        +++ b/.changesets/fix_skewer_boyfriend_forum_sleigh.md
        @@ -2,13 +2,13 @@
         
         Updated our underlying `apollo-rs` dependency on our `apollo-compiler` crate to bring in two nice improvements:
         
        -- **Fix validation performance bug
        +- **Fix validation performance bug**
         
           Adds a cache in fragment spread validation, fixing a situation where validating a query
           with many fragment spreads against a schema with many interfaces could take multiple
           seconds to validate.
         
        -- **Remove ariadne byte/char mapping
        +- **Remove ariadne byte/char mapping**
         
           Generating JSON or CLI reports for apollo-compiler diagnostics used a translation layer
           between byte offsets and character offsets, which cost some computation and memory
        
        From f73ead6fa4864b037f3d4664d9f7a0138d48917a Mon Sep 17 00:00:00 2001
        From: Jesse Rosenberger 
        Date: Mon, 10 Jun 2024 16:48:29 +0300
        Subject: [PATCH 9/9] prep release: v1.48.1
        
        ---
         .../config_bnjjj_fix_studio_selector.md       | 16 ------
         .changesets/fix_fix_content_type_error.md     | 13 -----
         .../fix_skewer_boyfriend_forum_sleigh.md      | 18 -------
         CHANGELOG.md                                  | 53 +++++++++++++++++++
         Cargo.lock                                    |  8 +--
         apollo-federation/Cargo.toml                  |  2 +-
         apollo-router-benchmarks/Cargo.toml           |  2 +-
         apollo-router-scaffold/Cargo.toml             |  2 +-
         .../templates/base/Cargo.toml                 |  2 +-
         .../templates/base/xtask/Cargo.toml           |  2 +-
         apollo-router/Cargo.toml                      |  4 +-
         .../tracing/docker-compose.datadog.yml        |  2 +-
         dockerfiles/tracing/docker-compose.jaeger.yml |  2 +-
         dockerfiles/tracing/docker-compose.zipkin.yml |  2 +-
         docs/source/federation-version-support.mdx    | 10 +++-
         helm/chart/router/Chart.yaml                  |  4 +-
         helm/chart/router/README.md                   |  6 +--
         scripts/install.sh                            |  2 +-
         18 files changed, 82 insertions(+), 68 deletions(-)
         delete mode 100644 .changesets/config_bnjjj_fix_studio_selector.md
         delete mode 100644 .changesets/fix_fix_content_type_error.md
         delete mode 100644 .changesets/fix_skewer_boyfriend_forum_sleigh.md
        
        diff --git a/.changesets/config_bnjjj_fix_studio_selector.md b/.changesets/config_bnjjj_fix_studio_selector.md
        deleted file mode 100644
        index ca95af9e3c..0000000000
        --- a/.changesets/config_bnjjj_fix_studio_selector.md
        +++ /dev/null
        @@ -1,16 +0,0 @@
        -### Rename the telemetry selector to get studio operation id ([PR #5337](https://github.com/apollographql/router/pull/5337))
        -
        -We introduced a new `trace_id` selector format in `1.48.0` which was misnamed. It's not a trace id, it's the Apollo Studio Operation ID. We've fixed this naming problem in this release.
        -
        -If you want to access this selector, here is an example:
        -
        -```yaml
        -telemetry:
        -  instrumentation:
        -    spans:
        -      router:
        -        "studio.operation.id":
        -            studio_operation_id: true
        -```
        -
        -By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/5337
        diff --git a/.changesets/fix_fix_content_type_error.md b/.changesets/fix_fix_content_type_error.md
        deleted file mode 100644
        index 0d182ded44..0000000000
        --- a/.changesets/fix_fix_content_type_error.md
        +++ /dev/null
        @@ -1,13 +0,0 @@
        -### Improve error message produced when subgraphs responses don't include an expected `content-type` header value ([Issue #5359](https://github.com/apollographql/router/issues/5359))
        -
        -To improve a common debuggability challenge when a subgraph response doesn't contain an expected `content-type` header value, the error message produced will include additional details about the error.
        -
        -Examples:
        -
        -   * ```
        -     HTTP fetch failed from 'test': subgraph response contains invalid 'content-type' header value \"application/json,application/json\"; expected content-type: application/json or content-type: application/graphql-response+json
        -      ```
        -   * ```
        -     HTTP fetch failed from 'test': subgraph response does not contain 'content-type' header; expected content-type: application/json or content-type: application/graphql-response+json
        -      ```
        -By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/5223
        \ No newline at end of file
        diff --git a/.changesets/fix_skewer_boyfriend_forum_sleigh.md b/.changesets/fix_skewer_boyfriend_forum_sleigh.md
        deleted file mode 100644
        index 992393b27b..0000000000
        --- a/.changesets/fix_skewer_boyfriend_forum_sleigh.md
        +++ /dev/null
        @@ -1,18 +0,0 @@
        -### Update `apollo-compiler` for two small improvements ([PR #5347](https://github.com/apollographql/router/pull/5347))
        -
        -Updated our underlying `apollo-rs` dependency on our `apollo-compiler` crate to bring in two nice improvements:
        -
        -- **Fix validation performance bug**
        -
        -  Adds a cache in fragment spread validation, fixing a situation where validating a query
        -  with many fragment spreads against a schema with many interfaces could take multiple
        -  seconds to validate.
        -
        -- **Remove ariadne byte/char mapping**
        -
        -  Generating JSON or CLI reports for apollo-compiler diagnostics used a translation layer
        -  between byte offsets and character offsets, which cost some computation and memory
        -  proportional to the size of the source text. The latest version of `ariadne` allows us to
        -  remove this translation.
        -
        -By [@goto-bus-stop](https://github.com/goto-bus-stop) in https://github.com/apollographql/router/pull/5347
        \ No newline at end of file
        diff --git a/CHANGELOG.md b/CHANGELOG.md
        index 8135084cde..0226015ac6 100644
        --- a/CHANGELOG.md
        +++ b/CHANGELOG.md
        @@ -4,6 +4,59 @@ All notable changes to Router will be documented in this file.
         
         This project adheres to [Semantic Versioning v2.0.0](https://semver.org/spec/v2.0.0.html).
         
        +# [1.48.1] - 2024-06-10
        +
        +## πŸ› Fixes
        +
        +### Improve error message produced when a subgraph response doesn't include an expected `content-type` header value ([Issue #5359](https://github.com/apollographql/router/issues/5359))
        +
        +To improve a common debuggability challenge when a subgraph response doesn't contain an expected `content-type` header value, the error message produced will include additional details about the error.
        +
        +Some examples of the improved error message:
        +
        +   * ```
        +     HTTP fetch failed from 'test': subgraph response contains invalid 'content-type' header value "application/json,application/json"; expected content-type: application/json or content-type: application/graphql-response+json
        +     ```
        +   * ```
        +     HTTP fetch failed from 'test': subgraph response does not contain 'content-type' header; expected content-type: application/json or content-type: application/graphql-response+json
        +     ```
        +By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/5223
        +
        +### Update `apollo-compiler` for two small improvements ([PR #5347](https://github.com/apollographql/router/pull/5347))
        +
        +Updated our underlying `apollo-rs` dependency on our `apollo-compiler` crate to bring in two nice improvements:
        +
        +- _Fix validation performance bug_
        +
        +  Adds a cache in fragment spread validation, fixing a situation where validating a query with many fragment spreads against a schema with many interfaces could take multiple seconds to validate.
        +
        +- _Remove ariadne byte/char mapping_
        +
        +  Generating JSON or CLI reports for apollo-compiler diagnostics used a translation layer between byte offsets and character offsets, which cost some computation and memory proportional to the size of the source text. The latest version of `ariadne` allows us to remove this translation.
        +
        +By [@goto-bus-stop](https://github.com/goto-bus-stop) in https://github.com/apollographql/router/pull/5347
        +
        +## πŸ“ƒ Configuration
        +
        +### Rename the telemetry selector which obtains the GraphOS operation id ([PR #5337](https://github.com/apollographql/router/pull/5337))
        +
        +Renames a misnamed `trace_id` selector introduced in [v1.48.0](https://github.com/apollographql/router/releases/tag/v1.48.0) to the value which it actually represents which is an Apollo GraphOS operation ID, rather than a trace ID.  Apologies for the confusion!  Unfortunately, we aren't able to produce an Apollo GraphOS trace ID at this time.
        +
        +If you want to access this operation ID selector, here is an example of how to apply it to your tracing spans:
        +
        +```yaml
        +telemetry:
        +  instrumentation:
        +    spans:
        +      router:
        +        "studio.operation.id":
        +            studio_operation_id: true
        +```
        +
        +This can be useful for more easily locating the operation in [GraphOS' Insights](https://www.apollographql.com/docs/graphos/metrics/operations) feature and finding applicable traces in Studio.
        +
        +By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/5337
        +
         # [1.48.0] - 2024-05-29
         
         ## πŸš€ Features
        diff --git a/Cargo.lock b/Cargo.lock
        index 83725f5370..c5dbbb16d1 100644
        --- a/Cargo.lock
        +++ b/Cargo.lock
        @@ -220,7 +220,7 @@ dependencies = [
         
         [[package]]
         name = "apollo-federation"
        -version = "1.48.1-rc.0"
        +version = "1.48.1"
         dependencies = [
          "apollo-compiler",
          "derive_more",
        @@ -262,7 +262,7 @@ dependencies = [
         
         [[package]]
         name = "apollo-router"
        -version = "1.48.1-rc.0"
        +version = "1.48.1"
         dependencies = [
          "access-json",
          "anyhow",
        @@ -425,7 +425,7 @@ dependencies = [
         
         [[package]]
         name = "apollo-router-benchmarks"
        -version = "1.48.1-rc.0"
        +version = "1.48.1"
         dependencies = [
          "apollo-parser",
          "apollo-router",
        @@ -441,7 +441,7 @@ dependencies = [
         
         [[package]]
         name = "apollo-router-scaffold"
        -version = "1.48.1-rc.0"
        +version = "1.48.1"
         dependencies = [
          "anyhow",
          "cargo-scaffold",
        diff --git a/apollo-federation/Cargo.toml b/apollo-federation/Cargo.toml
        index 009e1d1ba6..b2302b0c5e 100644
        --- a/apollo-federation/Cargo.toml
        +++ b/apollo-federation/Cargo.toml
        @@ -1,6 +1,6 @@
         [package]
         name = "apollo-federation"
        -version = "1.48.1-rc.0"
        +version = "1.48.1"
         authors = ["The Apollo GraphQL Contributors"]
         edition = "2021"
         description = "Apollo Federation"
        diff --git a/apollo-router-benchmarks/Cargo.toml b/apollo-router-benchmarks/Cargo.toml
        index 29c4ebdee5..09e520db79 100644
        --- a/apollo-router-benchmarks/Cargo.toml
        +++ b/apollo-router-benchmarks/Cargo.toml
        @@ -1,6 +1,6 @@
         [package]
         name = "apollo-router-benchmarks"
        -version = "1.48.1-rc.0"
        +version = "1.48.1"
         authors = ["Apollo Graph, Inc. "]
         edition = "2021"
         license = "Elastic-2.0"
        diff --git a/apollo-router-scaffold/Cargo.toml b/apollo-router-scaffold/Cargo.toml
        index a35f546241..354486871e 100644
        --- a/apollo-router-scaffold/Cargo.toml
        +++ b/apollo-router-scaffold/Cargo.toml
        @@ -1,6 +1,6 @@
         [package]
         name = "apollo-router-scaffold"
        -version = "1.48.1-rc.0"
        +version = "1.48.1"
         authors = ["Apollo Graph, Inc. "]
         edition = "2021"
         license = "Elastic-2.0"
        diff --git a/apollo-router-scaffold/templates/base/Cargo.toml b/apollo-router-scaffold/templates/base/Cargo.toml
        index 20170acea3..62ebdff3d5 100644
        --- a/apollo-router-scaffold/templates/base/Cargo.toml
        +++ b/apollo-router-scaffold/templates/base/Cargo.toml
        @@ -22,7 +22,7 @@ apollo-router = { path ="{{integration_test}}apollo-router" }
         apollo-router = { git="https://github.com/apollographql/router.git", branch="{{branch}}" }
         {{else}}
         # Note if you update these dependencies then also update xtask/Cargo.toml
        -apollo-router = "1.48.1-rc.0"
        +apollo-router = "1.48.1"
         {{/if}}
         {{/if}}
         async-trait = "0.1.52"
        diff --git a/apollo-router-scaffold/templates/base/xtask/Cargo.toml b/apollo-router-scaffold/templates/base/xtask/Cargo.toml
        index 89beb252d6..d6c86bde05 100644
        --- a/apollo-router-scaffold/templates/base/xtask/Cargo.toml
        +++ b/apollo-router-scaffold/templates/base/xtask/Cargo.toml
        @@ -13,7 +13,7 @@ apollo-router-scaffold = { path ="{{integration_test}}apollo-router-scaffold" }
         {{#if branch}}
         apollo-router-scaffold = { git="https://github.com/apollographql/router.git", branch="{{branch}}" }
         {{else}}
        -apollo-router-scaffold = { git = "https://github.com/apollographql/router.git", tag = "v1.48.1-rc.0" }
        +apollo-router-scaffold = { git = "https://github.com/apollographql/router.git", tag = "v1.48.1" }
         {{/if}}
         {{/if}}
         anyhow = "1.0.58"
        diff --git a/apollo-router/Cargo.toml b/apollo-router/Cargo.toml
        index 63eca16031..377108e858 100644
        --- a/apollo-router/Cargo.toml
        +++ b/apollo-router/Cargo.toml
        @@ -1,6 +1,6 @@
         [package]
         name = "apollo-router"
        -version = "1.48.1-rc.0"
        +version = "1.48.1"
         authors = ["Apollo Graph, Inc. "]
         repository = "https://github.com/apollographql/router/"
         documentation = "https://docs.rs/apollo-router"
        @@ -68,7 +68,7 @@ askama = "0.12.1"
         access-json = "0.1.0"
         anyhow = "1.0.80"
         apollo-compiler.workspace = true
        -apollo-federation = { path = "../apollo-federation", version = "=1.48.1-rc.0" }
        +apollo-federation = { path = "../apollo-federation", version = "=1.48.1" }
         arc-swap = "1.6.0"
         async-channel = "1.9.0"
         async-compression = { version = "0.4.6", features = [
        diff --git a/dockerfiles/tracing/docker-compose.datadog.yml b/dockerfiles/tracing/docker-compose.datadog.yml
        index b8e40a04c5..f04ac66fa6 100644
        --- a/dockerfiles/tracing/docker-compose.datadog.yml
        +++ b/dockerfiles/tracing/docker-compose.datadog.yml
        @@ -3,7 +3,7 @@ services:
         
           apollo-router:
             container_name: apollo-router
        -    image: ghcr.io/apollographql/router:v1.48.1-rc.0
        +    image: ghcr.io/apollographql/router:v1.48.1
             volumes:
               - ./supergraph.graphql:/etc/config/supergraph.graphql
               - ./router/datadog.router.yaml:/etc/config/configuration.yaml
        diff --git a/dockerfiles/tracing/docker-compose.jaeger.yml b/dockerfiles/tracing/docker-compose.jaeger.yml
        index d6c26bb1e1..c111539476 100644
        --- a/dockerfiles/tracing/docker-compose.jaeger.yml
        +++ b/dockerfiles/tracing/docker-compose.jaeger.yml
        @@ -4,7 +4,7 @@ services:
           apollo-router:
             container_name: apollo-router
             #build: ./router
        -    image: ghcr.io/apollographql/router:v1.48.1-rc.0
        +    image: ghcr.io/apollographql/router:v1.48.1
             volumes:
               - ./supergraph.graphql:/etc/config/supergraph.graphql
               - ./router/jaeger.router.yaml:/etc/config/configuration.yaml
        diff --git a/dockerfiles/tracing/docker-compose.zipkin.yml b/dockerfiles/tracing/docker-compose.zipkin.yml
        index 9ef4540a07..223c1ed6c4 100644
        --- a/dockerfiles/tracing/docker-compose.zipkin.yml
        +++ b/dockerfiles/tracing/docker-compose.zipkin.yml
        @@ -4,7 +4,7 @@ services:
           apollo-router:
             container_name: apollo-router
             build: ./router
        -    image: ghcr.io/apollographql/router:v1.48.1-rc.0
        +    image: ghcr.io/apollographql/router:v1.48.1
             volumes:
               - ./supergraph.graphql:/etc/config/supergraph.graphql
               - ./router/zipkin.router.yaml:/etc/config/configuration.yaml
        diff --git a/docs/source/federation-version-support.mdx b/docs/source/federation-version-support.mdx
        index 66194e4204..9fe67d5bb1 100644
        --- a/docs/source/federation-version-support.mdx
        +++ b/docs/source/federation-version-support.mdx
        @@ -37,7 +37,15 @@ The table below shows which version of federation each router release is compile
             
             
                 
        -            v1.46.0 and later (see latest releases)
        +            v1.48.0 and later (see latest releases)
        +        
        +        
        +            2.8.0
        +        
        +    
        +    
        +        
        +            v1.46.0 - v1.47.0
                 
                 
                     2.7.5
        diff --git a/helm/chart/router/Chart.yaml b/helm/chart/router/Chart.yaml
        index 284f7a67d1..ca518c7196 100644
        --- a/helm/chart/router/Chart.yaml
        +++ b/helm/chart/router/Chart.yaml
        @@ -20,10 +20,10 @@ type: application
         # so it matches the shape of our release process and release automation.
         # By proxy of that decision, this version uses SemVer 2.0.0, though the prefix
         # of "v" is not included.
        -version: 1.48.1-rc.0
        +version: 1.48.1
         
         # This is the version number of the application being deployed. This version number should be
         # incremented each time you make changes to the application. Versions are not expected to
         # follow Semantic Versioning. They should reflect the version the application is using.
         # It is recommended to use it with quotes.
        -appVersion: "v1.48.1-rc.0"
        +appVersion: "v1.48.1"
        diff --git a/helm/chart/router/README.md b/helm/chart/router/README.md
        index 6b5a587184..75677ed3eb 100644
        --- a/helm/chart/router/README.md
        +++ b/helm/chart/router/README.md
        @@ -2,7 +2,7 @@
         
         [router](https://github.com/apollographql/router) Rust Graph Routing runtime for Apollo Federation
         
        -![Version: 1.48.1-rc.0](https://img.shields.io/badge/Version-1.48.1--rc.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.48.1-rc.0](https://img.shields.io/badge/AppVersion-v1.48.1--rc.0-informational?style=flat-square)
        +![Version: 1.48.1](https://img.shields.io/badge/Version-1.48.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.48.1](https://img.shields.io/badge/AppVersion-v1.48.1-informational?style=flat-square)
         
         ## Prerequisites
         
        @@ -11,7 +11,7 @@
         ## Get Repo Info
         
         ```console
        -helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.48.1-rc.0
        +helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.48.1
         ```
         
         ## Install Chart
        @@ -19,7 +19,7 @@ helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.48.1-rc.0
         **Important:** only helm3 is supported
         
         ```console
        -helm upgrade --install [RELEASE_NAME] oci://ghcr.io/apollographql/helm-charts/router --version 1.48.1-rc.0 --values my-values.yaml
        +helm upgrade --install [RELEASE_NAME] oci://ghcr.io/apollographql/helm-charts/router --version 1.48.1 --values my-values.yaml
         ```
         
         _See [configuration](#configuration) below._
        diff --git a/scripts/install.sh b/scripts/install.sh
        index 8353a59187..0a905d7fb7 100755
        --- a/scripts/install.sh
        +++ b/scripts/install.sh
        @@ -11,7 +11,7 @@ BINARY_DOWNLOAD_PREFIX="https://github.com/apollographql/router/releases/downloa
         
         # Router version defined in apollo-router's Cargo.toml
         # Note: Change this line manually during the release steps.
        -PACKAGE_VERSION="v1.48.1-rc.0"
        +PACKAGE_VERSION="v1.48.1"
         
         download_binary() {
             downloader --check