From 18913448ec0700564d040034a24d24a6381ef33e Mon Sep 17 00:00:00 2001 From: Tim Hingston Date: Fri, 6 Sep 2024 14:00:35 +1000 Subject: [PATCH 01/77] Add docs for enhanced OTel tracing in Studio --- docs/source/configuration/overview.mdx | 14 ++++ .../telemetry/apollo-telemetry.mdx | 64 +++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/docs/source/configuration/overview.mdx b/docs/source/configuration/overview.mdx index 13e6991a6a..c96db9d4fc 100644 --- a/docs/source/configuration/overview.mdx +++ b/docs/source/configuration/overview.mdx @@ -865,6 +865,20 @@ You won't see an immediate change in checks behavior when you first turn on exte + + +### Enhanced tracing in Studio via OpenTelemetry + + + + + +Beginning in v1.49.0, the router supports sending traces to Studio via the more detailed OTel (OpenTelemetry) protocol. +Support for OTel traces has historically only been available for 3rd party APM tools. With this option, +Studio can now provide a much more granular view of Router internals than the legacy Apollo tracing protocol. + +See [Enhanced tracing in Studio via OTel](./telemetry/apollo-telemetry#enhanced-tracing-in-studio-via-opentelemetry). + ### Safelisting with persisted queries You can enhance your graph's security with GraphOS Router by maintaining a persisted query list (PQL), an operation safelist made by your first-party apps. As opposed to automatic persisted queries (APQ) where operations are automatically cached, operations must be preregistered to the PQL. Once configured, the router checks incoming requests against the PQL. diff --git a/docs/source/configuration/telemetry/apollo-telemetry.mdx b/docs/source/configuration/telemetry/apollo-telemetry.mdx index c5f6c0c609..d4e276118e 100644 --- a/docs/source/configuration/telemetry/apollo-telemetry.mdx +++ b/docs/source/configuration/telemetry/apollo-telemetry.mdx @@ -72,6 +72,70 @@ telemetry: field_level_instrumentation_sampler: always_off ``` + + +### Enhanced tracing in Studio via OpenTelemetry + + + + + +Beginning in v1.49.0, the router supports sending traces to Studio via the more detailed OTel (OpenTelemetry) protocol. +Support for OTel traces has historically only been available for 3rd party APM tools. With this option, +Studio can now provide a much more granular view of Router internals than the legacy Apollo tracing protocol. + +Benefits include: + +- A comprehensive way to visualize the Router execution path in Studio. +- Additional spans that were previously not included in Studio traces, such as query parsing, planning, execution, and more. +- Additional attributes including HTTP request details, REST connector details, and more. + +It is expected that this will become the default in a future version of Router. + +#### Configuration + +This change adds a new configuration option `telemetry.apollo.experimental_otlp_tracing_sampler`. Use this option to send +a percentage of traces to Studio via OTLP instead of the native Apollo Usage Reporting protocol. Supported values: + +- `always_off` (default): send all traces via the legacy Apollo Usage Reporting protocol. +- `always_on`: send all traces via OTLP. +- `0.0 - 1.0` (used for testing): the ratio of traces to send via OTLP (0.5 = 50 / 50). + +Note that this sampler is only applied _after_ the common tracing sampler, for example: + +#### Sample 1% of traces, send all traces via OTLP: + +```yaml +telemetry: + apollo: + # Send all traces via OTLP + experimental_otlp_tracing_sampler: always_on + + exporters: + tracing: + common: + # Sample traces at 1% of all traffic + sampler: 0.01 +``` + +OTel traces sent to Studio will not necessarily be identical to the ones sent to 3rd Party APM tools via OTLP: + +- Only specific OTLP attributes will be included for parity with what is provided in legacy traces today. This ensures that data privacy + is maintained in an equivalent manner. The existing Router configuration options for Apollo telemetry will continue to function + with OTLP traces, such as forwarding of GraphQL errors, headers, and variables. +- Some features of OTLP traces may only be available in Studio and not in 3rd Party APM tools (e.g. resolver-level timing information from + [Federated Tracing](../../federation/metrics/#enabling-federated-tracing)). + + + +This change results in using a new wire protocol for traces, and some users may experience an increase in tracing traffic +to GraphOS Studio due to the additional detail being captured. In exceptional situations it may be necessary to send fewer traces. +This can be achieved via sending fewer traces (`telemetry.exporters.tracing.common.sampler`) or as a last resort, falling back +to the old protocol via `telemetry.apollo.otlp_tracing_sampler` to send fewer OTLP traces or fully disable them. +Any performance regressions due to the new tracing protocol should also be reported to the Apollo support team. + + + ### Experimental local field metrics Apollo Router can send field-level metrics to GraphOS without using FTV1 tracing. This feature is experimental and is not yet displayable in GraphOS Studio. From b078823752c483d155fbe1b81a64edd6e1635ffc Mon Sep 17 00:00:00 2001 From: Edward Huang Date: Thu, 17 Oct 2024 07:03:20 -0700 Subject: [PATCH 02/77] docs: remove docs-publish workflow for dev (#6168) --- .github/workflows/docs-publish.yml | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 .github/workflows/docs-publish.yml diff --git a/.github/workflows/docs-publish.yml b/.github/workflows/docs-publish.yml deleted file mode 100644 index 7da79e0f58..0000000000 --- a/.github/workflows/docs-publish.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: Deploy docs to production - -on: - push: - branches: - - main - paths: - - docs/** - -jobs: - publish: - uses: apollographql/docs/.github/workflows/publish.yml@main - secrets: - NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} - NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} From d41a1f00e9b52be0bb6807091184e25a4b6b4b8f Mon Sep 17 00:00:00 2001 From: Gary Pennington Date: Fri, 18 Oct 2024 15:45:30 +0100 Subject: [PATCH 03/77] If subgraph batching, do not log the full response when failing to notify a waiter (#6150) --- ...pen_log_less_error_for_subgraph_batching.md | 7 +++++++ apollo-router/src/services/subgraph_service.rs | 18 +++++++++++------- 2 files changed, 18 insertions(+), 7 deletions(-) create mode 100644 .changesets/fix_garypen_log_less_error_for_subgraph_batching.md diff --git a/.changesets/fix_garypen_log_less_error_for_subgraph_batching.md b/.changesets/fix_garypen_log_less_error_for_subgraph_batching.md new file mode 100644 index 0000000000..f81796d01a --- /dev/null +++ b/.changesets/fix_garypen_log_less_error_for_subgraph_batching.md @@ -0,0 +1,7 @@ +### If subgraph batching, do not log response data for notification failure ([PR #6150](https://github.com/apollographql/router/pull/6150)) + +A subgraph response may contain a lot of data and/or PII data. + +For a subgraph batching operation, we should not log out the entire subgraph response when failing to notify a waiting batch participant. + +By [@garypen](https://github.com/garypen) in https://github.com/apollographql/router/pull/6150 \ 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 2b99f3bd24..2cc367b614 100644 --- a/apollo-router/src/services/subgraph_service.rs +++ b/apollo-router/src/services/subgraph_service.rs @@ -1047,6 +1047,8 @@ pub(crate) async fn notify_batch_query( Err(e) => { for tx in senders { // Try to notify all waiters. If we can't notify an individual sender, then log an error + // which, unlike failing to notify on success (see below), contains the the entire error + // response. if let Err(log_error) = tx.send(Err(Box::new(e.clone()))).map_err(|error| { FetchError::SubrequestBatchingError { service: service.clone(), @@ -1076,13 +1078,15 @@ pub(crate) async fn notify_batch_query( // graphql_response, so zip_eq shouldn't panic. // Use the tx to send a graphql_response message to each waiter. for (response, sender) in rs.into_iter().zip_eq(senders) { - if let Err(log_error) = - sender - .send(Ok(response)) - .map_err(|error| FetchError::SubrequestBatchingError { - service: service.to_string(), - reason: format!("tx send failed: {error:?}"), - }) + if let Err(log_error) = sender + .send(Ok(response)) + // If we fail to notify the waiter that our request succeeded, do not log + // out the entire response since this may be substantial and/or contain + // PII data. Simply log that the send failed. + .map_err(|_error| FetchError::SubrequestBatchingError { + service: service.to_string(), + reason: "tx send failed".to_string(), + }) { tracing::error!(service, error=%log_error, "failed to notify sender that batch processing succeeded"); } From 146f840e8c507b44357a8908da2e191235a7694e Mon Sep 17 00:00:00 2001 From: Geoffroy Couprie Date: Mon, 21 Oct 2024 10:18:56 +0200 Subject: [PATCH 04/77] Add a subgraph request id (#5858) This is a unique string identifying a subgraph request and response, allowing plugins and coprocessors to keep some state per subgraph request by matching on this id. It is available in coprocessors as subgraphRequestId and rhai scripts as request.subgraph.id and response.subgraph.id. Co-authored-by: Coenen Benjamin --- .changesets/feat_geal_subgraph_request_id.md | 5 + apollo-router/src/batching.rs | 148 +++++++++++++++++- ...nfiguration__tests__schema_generation.snap | 10 ++ .../src/plugin/test/mock/subgraph.rs | 8 +- .../src/plugins/authentication/subgraph.rs | 2 + apollo-router/src/plugins/coprocessor/mod.rs | 13 ++ apollo-router/src/plugins/coprocessor/test.rs | 92 ++++++----- apollo-router/src/plugins/headers.rs | 5 + .../src/plugins/record_replay/replay.rs | 1 + apollo-router/src/plugins/rhai/engine.rs | 14 ++ apollo-router/src/plugins/rhai/tests.rs | 4 +- .../plugins/traffic_shaping/deduplication.rs | 4 + apollo-router/src/services/external.rs | 8 + apollo-router/src/services/subgraph.rs | 59 +++++++ .../src/services/subgraph_service.rs | 24 ++- ...hes_subgraph_request_ids_to_responses.snap | 27 ++++ apollo-router/src/test_harness.rs | 1 + .../tests/fixtures/batching/subgraph_id.rhai | 0 .../fixtures/batching/subgraph_id.router.yaml | 15 ++ .../tests/fixtures/request_response_test.rhai | 7 + apollo-router/tests/integration/redis.rs | 2 +- ...gration__redis__entity_cache_basic-2.snap} | 0 ...gration__redis__entity_cache_basic-3.snap} | 0 ...gration__redis__entity_cache_basic-4.snap} | 0 ...gration__redis__entity_cache_basic-5.snap} | 0 ...tegration__redis__entity_cache_basic.snap} | 0 docs/shared/coproc-typical-config.mdx | 2 + docs/source/customizations/coprocessor.mdx | 19 +++ docs/source/customizations/overview.mdx | 2 +- docs/source/customizations/rhai-api.mdx | 4 + 30 files changed, 414 insertions(+), 62 deletions(-) create mode 100644 .changesets/feat_geal_subgraph_request_id.md create mode 100644 apollo-router/src/snapshots/apollo_router__batching__tests__it_matches_subgraph_request_ids_to_responses.snap create mode 100644 apollo-router/tests/fixtures/batching/subgraph_id.rhai create mode 100644 apollo-router/tests/fixtures/batching/subgraph_id.router.yaml rename apollo-router/tests/integration/snapshots/{integration_tests__integration__redis__entity_cache-2.snap => integration_tests__integration__redis__entity_cache_basic-2.snap} (100%) rename apollo-router/tests/integration/snapshots/{integration_tests__integration__redis__entity_cache-3.snap => integration_tests__integration__redis__entity_cache_basic-3.snap} (100%) rename apollo-router/tests/integration/snapshots/{integration_tests__integration__redis__entity_cache-4.snap => integration_tests__integration__redis__entity_cache_basic-4.snap} (100%) rename apollo-router/tests/integration/snapshots/{integration_tests__integration__redis__entity_cache-5.snap => integration_tests__integration__redis__entity_cache_basic-5.snap} (100%) rename apollo-router/tests/integration/snapshots/{integration_tests__integration__redis__entity_cache.snap => integration_tests__integration__redis__entity_cache_basic.snap} (100%) diff --git a/.changesets/feat_geal_subgraph_request_id.md b/.changesets/feat_geal_subgraph_request_id.md new file mode 100644 index 0000000000..b5e0934132 --- /dev/null +++ b/.changesets/feat_geal_subgraph_request_id.md @@ -0,0 +1,5 @@ +### Add a subgraph request id ([PR #5858](https://github.com/apollographql/router/pull/5858)) + +This is a unique string identifying a subgraph request and response, allowing plugins and coprocessors to keep some state per subgraph request by matching on this id. It is available in coprocessors as `subgraphRequestId` and rhai scripts as `request.subgraph.id` and `response.subgraph.id`. + +By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/5858 \ No newline at end of file diff --git a/apollo-router/src/batching.rs b/apollo-router/src/batching.rs index b570587b6f..e8ada106a3 100644 --- a/apollo-router/src/batching.rs +++ b/apollo-router/src/batching.rs @@ -28,6 +28,7 @@ use crate::services::http::HttpClientServiceFactory; use crate::services::process_batches; use crate::services::router::body::get_body_bytes; use crate::services::router::body::RouterBody; +use crate::services::subgraph::SubgraphRequestId; use crate::services::SubgraphRequest; use crate::services::SubgraphResponse; use crate::Context; @@ -426,7 +427,7 @@ pub(crate) async fn assemble_batch( ) -> Result< ( String, - Vec, + Vec<(Context, SubgraphRequestId)>, http::Request, Vec>>, ), @@ -445,8 +446,8 @@ pub(crate) async fn assemble_batch( // Retain the various contexts for later use let contexts = requests .iter() - .map(|x| x.context.clone()) - .collect::>(); + .map(|request| (request.context.clone(), request.id.clone())) + .collect::>(); // Grab the common info from the first request let first_request = requests .into_iter() @@ -470,19 +471,31 @@ mod tests { use std::sync::Arc; use std::time::Duration; + use http::header::ACCEPT; + use http::header::CONTENT_TYPE; use tokio::sync::oneshot; + use tower::ServiceExt; + use wiremock::matchers; + use wiremock::MockServer; + use wiremock::ResponseTemplate; use super::assemble_batch; use super::Batch; use super::BatchQueryInfo; use crate::graphql; + use crate::graphql::Request; + use crate::layers::ServiceExt as LayerExt; use crate::plugins::traffic_shaping::Http2Config; use crate::query_planner::fetch::QueryHash; use crate::services::http::HttpClientServiceFactory; + use crate::services::router; + use crate::services::subgraph; + use crate::services::subgraph::SubgraphRequestId; use crate::services::SubgraphRequest; use crate::services::SubgraphResponse; use crate::Configuration; use crate::Context; + use crate::TestHarness; #[tokio::test(flavor = "multi_thread")] async fn it_assembles_batch() { @@ -523,7 +536,7 @@ mod tests { let output_context_ids = contexts .iter() - .map(|r| r.id.clone()) + .map(|r| r.0.id.clone()) .collect::>(); // Make sure all of our contexts are preserved during assembly assert_eq!(input_context_ids, output_context_ids); @@ -562,6 +575,7 @@ mod tests { .unwrap(), context: Context::new(), subgraph_name: None, + id: SubgraphRequestId(String::new()), }; tx.send(Ok(response)).unwrap(); @@ -722,4 +736,130 @@ mod tests { .await .is_err()); } + + fn expect_batch(request: &wiremock::Request) -> ResponseTemplate { + let requests: Vec = request.body_json().unwrap(); + + // Extract info about this operation + let (subgraph, count): (String, usize) = { + let re = regex::Regex::new(r"entry([AB])\(count:([0-9]+)\)").unwrap(); + let captures = re.captures(requests[0].query.as_ref().unwrap()).unwrap(); + + (captures[1].to_string(), captures[2].parse().unwrap()) + }; + + // We should have gotten `count` elements + assert_eq!(requests.len(), count); + + // Each element should have be for the specified subgraph and should have a field selection + // of index. + // Note: The router appends info to the query, so we append it at this check + for (index, request) in requests.into_iter().enumerate() { + assert_eq!( + request.query, + Some(format!( + "query op{index}__{}__0{{entry{}(count:{count}){{index}}}}", + subgraph.to_lowercase(), + subgraph + )) + ); + } + + ResponseTemplate::new(200).set_body_json( + (0..count) + .map(|index| { + serde_json::json!({ + "data": { + format!("entry{subgraph}"): { + "index": index + } + } + }) + }) + .collect::>(), + ) + } + + #[tokio::test(flavor = "multi_thread")] + async fn it_matches_subgraph_request_ids_to_responses() { + // Create a wiremock server for each handler + let mock_server = MockServer::start().await; + mock_server + .register( + wiremock::Mock::given(matchers::method("POST")) + .and(matchers::path("/a")) + .respond_with(expect_batch) + .expect(1), + ) + .await; + + let schema = include_str!("../tests/fixtures/batching/schema.graphql"); + let service = TestHarness::builder() + .configuration_json(serde_json::json!({ + "include_subgraph_errors": { + "all": true + }, + "batching": { + "enabled": true, + "mode": "batch_http_link", + "subgraph": { + "all": { + "enabled": true + } + } + }, + "override_subgraph_url": { + "a": format!("{}/a", mock_server.uri()) + }})) + .unwrap() + .schema(schema) + .subgraph_hook(move |_subgraph_name, service| { + service + .map_future_with_request_data( + |r: &subgraph::Request| r.id.clone(), + |id, f| async move { + let r: subgraph::ServiceResult = f.await; + assert_eq!(id, r.as_ref().map(|r| r.id.clone()).unwrap()); + r + }, + ) + .boxed() + }) + .with_subgraph_network_requests() + .build_router() + .await + .unwrap(); + + let requests: Vec<_> = (0..3) + .map(|index| { + Request::fake_builder() + .query(format!("query op{index}{{ entryA(count: 3) {{ index }} }}")) + .build() + }) + .collect(); + let request = serde_json::to_value(requests).unwrap(); + + let context = Context::new(); + let request = router::Request { + context, + router_request: http::Request::builder() + .method("POST") + .header(CONTENT_TYPE, "application/json") + .header(ACCEPT, "application/json") + .body(serde_json::to_vec(&request).unwrap().into()) + .unwrap(), + }; + + let response = service + .oneshot(request) + .await + .unwrap() + .next_response() + .await + .unwrap() + .unwrap(); + + let response: serde_json::Value = serde_json::from_slice(&response).unwrap(); + insta::assert_json_snapshot!(response); + } } 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 a1939bc42a..adccdca79a 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 @@ -5930,6 +5930,11 @@ expression: "&schema" "description": "Send the service name", "type": "boolean" }, + "subgraph_request_id": { + "default": false, + "description": "Send the subgraph request id", + "type": "boolean" + }, "uri": { "default": false, "description": "Send the subgraph URI", @@ -5971,6 +5976,11 @@ expression: "&schema" "default": false, "description": "Send the http status", "type": "boolean" + }, + "subgraph_request_id": { + "default": false, + "description": "Send the subgraph request id", + "type": "boolean" } }, "type": "object" diff --git a/apollo-router/src/plugin/test/mock/subgraph.rs b/apollo-router/src/plugin/test/mock/subgraph.rs index 46321b585b..ee38234606 100644 --- a/apollo-router/src/plugin/test/mock/subgraph.rs +++ b/apollo-router/src/plugin/test/mock/subgraph.rs @@ -209,7 +209,12 @@ impl Service for MockSubgraph { let http_response = http_response_builder .body(response.clone()) .expect("Response is serializable; qed"); - SubgraphResponse::new_from_response(http_response, req.context, "test".to_string()) + SubgraphResponse::new_from_response( + http_response, + req.context, + "test".to_string(), + req.id, + ) } else { let error = crate::error::Error::builder() .message(format!( @@ -222,6 +227,7 @@ impl Service for MockSubgraph { SubgraphResponse::fake_builder() .error(error) .context(req.context) + .id(req.id) .build() }; future::ok(response) diff --git a/apollo-router/src/plugins/authentication/subgraph.rs b/apollo-router/src/plugins/authentication/subgraph.rs index 9dce2b1e45..568aa9c8ac 100644 --- a/apollo-router/src/plugins/authentication/subgraph.rs +++ b/apollo-router/src/plugins/authentication/subgraph.rs @@ -508,6 +508,7 @@ mod test { use crate::graphql::Request; use crate::plugin::test::MockSubgraphService; use crate::query_planner::fetch::OperationKind; + use crate::services::subgraph::SubgraphRequestId; use crate::services::SubgraphRequest; use crate::services::SubgraphResponse; use crate::Context; @@ -806,6 +807,7 @@ mod test { http::Response::default(), Context::new(), req.subgraph_name.unwrap_or_else(|| String::from("test")), + SubgraphRequestId(String::new()), )) } diff --git a/apollo-router/src/plugins/coprocessor/mod.rs b/apollo-router/src/plugins/coprocessor/mod.rs index c986f2629a..e979776c8a 100644 --- a/apollo-router/src/plugins/coprocessor/mod.rs +++ b/apollo-router/src/plugins/coprocessor/mod.rs @@ -291,6 +291,8 @@ pub(super) struct SubgraphRequestConf { pub(super) method: bool, /// Send the service name pub(super) service_name: bool, + /// Send the subgraph request id + pub(super) subgraph_request_id: bool, } /// What information is passed to a subgraph request/response stage @@ -310,6 +312,8 @@ pub(super) struct SubgraphResponseConf { pub(super) service_name: bool, /// Send the http status pub(super) status_code: bool, + /// Send the subgraph request id + pub(super) subgraph_request_id: bool, } /// Configures the externalization plugin @@ -1012,6 +1016,9 @@ where let uri = request_config.uri.then(|| parts.uri.to_string()); let subgraph_name = service_name.clone(); let service_name = request_config.service_name.then_some(service_name); + let subgraph_request_id = request_config + .subgraph_request_id + .then_some(request.id.clone()); let payload = Externalizable::subgraph_builder() .stage(PipelineStep::SubgraphRequest) @@ -1023,6 +1030,7 @@ where .method(parts.method.to_string()) .and_service_name(service_name) .and_uri(uri) + .and_subgraph_request_id(subgraph_request_id) .build(); tracing::debug!(?payload, "externalized output"); @@ -1081,6 +1089,7 @@ where response: http_response, context: request.context, subgraph_name: Some(subgraph_name), + id: request.id, }; if let Some(context) = co_processor_output.context { @@ -1168,6 +1177,9 @@ where .transpose()?; let context_to_send = response_config.context.then(|| response.context.clone()); let service_name = response_config.service_name.then_some(service_name); + let subgraph_request_id = response_config + .subgraph_request_id + .then_some(response.id.clone()); let payload = Externalizable::subgraph_builder() .stage(PipelineStep::SubgraphResponse) @@ -1177,6 +1189,7 @@ where .and_context(context_to_send) .and_status_code(status_to_send) .and_service_name(service_name) + .and_subgraph_request_id(subgraph_request_id) .build(); tracing::debug!(?payload, "externalized output"); diff --git a/apollo-router/src/plugins/coprocessor/test.rs b/apollo-router/src/plugins/coprocessor/test.rs index 50786f336d..a2b9374fb9 100644 --- a/apollo-router/src/plugins/coprocessor/test.rs +++ b/apollo-router/src/plugins/coprocessor/test.rs @@ -15,6 +15,7 @@ mod tests { use router::body::RouterBody; use serde_json::json; use serde_json_bytes::Value; + use services::subgraph::SubgraphRequestId; use tower::BoxError; use tower::ServiceExt; @@ -279,12 +280,8 @@ mod tests { let subgraph_stage = SubgraphStage { request: SubgraphRequestConf { condition: Default::default(), - headers: false, - context: false, body: true, - uri: false, - method: false, - service_name: false, + ..Default::default() }, response: Default::default(), }; @@ -342,12 +339,9 @@ mod tests { let subgraph_stage = SubgraphStage { request: SubgraphRequestConf { condition: Default::default(), - headers: false, - context: false, body: true, - uri: false, - method: false, - service_name: false, + subgraph_request_id: true, + ..Default::default() }, response: Default::default(), }; @@ -384,16 +378,27 @@ mod tests { req.subgraph_request.into_body().query.unwrap() ); + // this should be the same as the initial request id + assert_eq!(&*req.id, "5678"); + Ok(subgraph::Response::builder() .data(json!({ "test": 1234_u32 })) .errors(Vec::new()) .extensions(crate::json_ext::Object::new()) .context(req.context) + .id(req.id) .build()) }); - let mock_http_client = mock_with_callback(move |_: http::Request| { + let mock_http_client = mock_with_callback(move |req: http::Request| { Box::pin(async { + let deserialized_request: Externalizable = + serde_json::from_slice(&hyper::body::to_bytes(req.into_body()).await.unwrap()) + .unwrap(); + assert_eq!( + deserialized_request.subgraph_request_id.as_deref(), + Some("5678") + ); Ok(http::Response::builder() .body(RouterBody::from( r#"{ @@ -438,7 +443,8 @@ mod tests { } }, "serviceName": "service name shouldn't change", - "uri": "http://thisurihaschanged" + "uri": "http://thisurihaschanged", + "subgraphRequestId": "9abc" }"#, )) .unwrap()) @@ -452,18 +458,15 @@ mod tests { "my_subgraph_service_name".to_string(), ); - let request = subgraph::Request::fake_builder().build(); + let mut request = subgraph::Request::fake_builder().build(); + request.id = SubgraphRequestId("5678".to_string()); + + let response = service.oneshot(request).await.unwrap(); + assert_eq!("5678", &*response.id); assert_eq!( serde_json_bytes::json!({ "test": 1234_u32 }), - service - .oneshot(request) - .await - .unwrap() - .response - .into_body() - .data - .unwrap() + response.response.into_body().data.unwrap() ); } @@ -480,12 +483,8 @@ mod tests { SelectorOrValue::Value("value".to_string().into()), ]) .into(), - headers: false, - context: false, body: true, - uri: false, - method: false, - service_name: false, + ..Default::default() }, response: Default::default(), }; @@ -554,12 +553,8 @@ mod tests { let subgraph_stage = SubgraphStage { request: SubgraphRequestConf { condition: Default::default(), - headers: false, - context: false, body: true, - uri: false, - method: false, - service_name: false, + ..Default::default() }, response: Default::default(), }; @@ -624,12 +619,8 @@ mod tests { let subgraph_stage = SubgraphStage { request: SubgraphRequestConf { condition: Default::default(), - headers: false, - context: false, body: true, - uri: false, - method: false, - service_name: false, + ..Default::default() }, response: Default::default(), }; @@ -689,11 +680,9 @@ mod tests { request: Default::default(), response: SubgraphResponseConf { condition: Default::default(), - headers: false, - context: false, body: true, - service_name: false, - status_code: false, + subgraph_request_id: true, + ..Default::default() }, }; @@ -703,16 +692,23 @@ mod tests { mock_subgraph_service .expect_call() .returning(|req: subgraph::Request| { + assert_eq!(&*req.id, "5678"); Ok(subgraph::Response::builder() .data(json!({ "test": 1234_u32 })) .errors(Vec::new()) .extensions(crate::json_ext::Object::new()) .context(req.context) + .id(req.id) .build()) }); - let mock_http_client = mock_with_callback(move |_: http::Request| { - Box::pin(async { + let mock_http_client = mock_with_callback(move |r: http::Request| { + Box::pin(async move { + let (_, body) = r.into_parts(); + let body: Value = serde_json::from_slice(&body.to_bytes().await.unwrap()).unwrap(); + let subgraph_id = body.get("subgraphRequestId").unwrap(); + assert_eq!(subgraph_id.as_str(), Some("5678")); + Ok(http::Response::builder() .body(RouterBody::from( r#"{ @@ -756,7 +752,8 @@ mod tests { "accepts-multipart": false, "this-is-a-test-context": 42 } - } + }, + "subgraphRequestId": "9abc" }"#, )) .unwrap()) @@ -770,7 +767,8 @@ mod tests { "my_subgraph_service_name".to_string(), ); - let request = subgraph::Request::fake_builder().build(); + let mut request = subgraph::Request::fake_builder().build(); + request.id = SubgraphRequestId("5678".to_string()); let response = service.oneshot(request).await.unwrap(); @@ -779,6 +777,7 @@ mod tests { response.response.headers().get("cookie").unwrap(), "tasty_cookie=strawberry" ); + assert_eq!(&*response.id, "5678"); assert_eq!( response @@ -807,11 +806,8 @@ mod tests { default: None, }) .into(), - headers: false, - context: false, body: true, - service_name: false, - status_code: false, + ..Default::default() }, }; diff --git a/apollo-router/src/plugins/headers.rs b/apollo-router/src/plugins/headers.rs index 1e52cd444c..c6e0082cfd 100644 --- a/apollo-router/src/plugins/headers.rs +++ b/apollo-router/src/plugins/headers.rs @@ -454,6 +454,7 @@ mod test { use std::str::FromStr; use std::sync::Arc; + use subgraph::SubgraphRequestId; use tower::BoxError; use super::*; @@ -863,6 +864,7 @@ mod test { query_hash: Default::default(), authorization: Default::default(), executable_document: None, + id: SubgraphRequestId(String::new()), }; service.modify_request(&mut request); let headers = request @@ -935,6 +937,7 @@ mod test { query_hash: Default::default(), authorization: Default::default(), executable_document: None, + id: SubgraphRequestId(String::new()), }; service.modify_request(&mut request); let headers = request @@ -956,6 +959,7 @@ mod test { http::Response::default(), Context::new(), req.subgraph_name.unwrap_or_default(), + SubgraphRequestId(String::new()), )) } @@ -998,6 +1002,7 @@ mod test { query_hash: Default::default(), authorization: Default::default(), executable_document: None, + id: SubgraphRequestId(String::new()), } } diff --git a/apollo-router/src/plugins/record_replay/replay.rs b/apollo-router/src/plugins/record_replay/replay.rs index dc79380f13..814e3e750e 100644 --- a/apollo-router/src/plugins/record_replay/replay.rs +++ b/apollo-router/src/plugins/record_replay/replay.rs @@ -219,6 +219,7 @@ impl Plugin for Replay { http::Response::new(fetch.response.chunks[0].clone()), req.context.clone(), subgraph_name.clone(), + req.id.clone(), ); let runtime_variables = req.subgraph_request.body().variables.clone(); diff --git a/apollo-router/src/plugins/rhai/engine.rs b/apollo-router/src/plugins/rhai/engine.rs index 23c084cb53..fde2fa8e7d 100644 --- a/apollo-router/src/plugins/rhai/engine.rs +++ b/apollo-router/src/plugins/rhai/engine.rs @@ -692,6 +692,13 @@ mod router_plugin { *obj.uri_mut() = uri; Ok(()) } + + #[rhai_fn(get = "subgraph_request_id", pure, return_raw)] + pub(crate) fn get_subgraph_id( + obj: &mut SharedMut, + ) -> Result> { + Ok(obj.with_mut(|request| request.id.to_string())) + } // End of SubgraphRequest specific section #[rhai_fn(get = "headers", pure, return_raw)] @@ -790,6 +797,13 @@ mod router_plugin { Ok(obj.with_mut(|response| response.response.headers().clone())) } + #[rhai_fn(get = "subgraph_request_id", pure, return_raw)] + pub(crate) fn get_subgraph_id_response( + obj: &mut SharedMut, + ) -> Result> { + Ok(obj.with_mut(|response| response.id.to_string())) + } + /*TODO: reenable when https://github.com/apollographql/router/issues/3642 is decided #[rhai_fn(get = "body", pure, return_raw)] pub(crate) fn get_originating_body_router_response( diff --git a/apollo-router/src/plugins/rhai/tests.rs b/apollo-router/src/plugins/rhai/tests.rs index 7b5843df14..dd3d4080f6 100644 --- a/apollo-router/src/plugins/rhai/tests.rs +++ b/apollo-router/src/plugins/rhai/tests.rs @@ -669,7 +669,7 @@ async fn it_can_process_string_subgraph_forbidden() { if let Err(error) = call_rhai_function("process_subgraph_response_string").await { let processed_error = process_error(error); assert_eq!(processed_error.status, StatusCode::INTERNAL_SERVER_ERROR); - assert_eq!(processed_error.message, Some("rhai execution error: 'Runtime error: I have raised an error (line 244, position 5)'".to_string())); + assert_eq!(processed_error.message, Some("rhai execution error: 'Runtime error: I have raised an error (line 251, position 5)'".to_string())); } else { // Test failed panic!("error processed incorrectly"); @@ -697,7 +697,7 @@ async fn it_cannot_process_om_subgraph_missing_message_and_body() { assert_eq!( processed_error.message, Some( - "rhai execution error: 'Runtime error: #{\"status\": 400} (line 255, position 5)'" + "rhai execution error: 'Runtime error: #{\"status\": 400} (line 262, position 5)'" .to_string() ) ); diff --git a/apollo-router/src/plugins/traffic_shaping/deduplication.rs b/apollo-router/src/plugins/traffic_shaping/deduplication.rs index 639d0d12b9..0df2574eb4 100644 --- a/apollo-router/src/plugins/traffic_shaping/deduplication.rs +++ b/apollo-router/src/plugins/traffic_shaping/deduplication.rs @@ -49,6 +49,7 @@ impl Clone for CloneSubgraphResponse { response: http_ext::Response::from(&self.0.response).inner, context: self.0.context.clone(), subgraph_name: self.0.subgraph_name.clone(), + id: self.0.id.clone(), }) } } @@ -105,6 +106,7 @@ where response.0.response, request.context, request.subgraph_name.unwrap_or_default(), + request.id, ) }) .map_err(|e| e.into()) @@ -121,6 +123,7 @@ where let context = request.context.clone(); let authorization_cache_key = request.authorization.clone(); + let id = request.id.clone(); let cache_key = ((&request.subgraph_request).into(), authorization_cache_key); let res = { // when _drop_signal is dropped, either by getting out of the block, returning @@ -162,6 +165,7 @@ where response.0.response, context, response.0.subgraph_name.unwrap_or_default(), + id, ) }); } diff --git a/apollo-router/src/services/external.rs b/apollo-router/src/services/external.rs index bf3ff9fb9c..c356ddd39c 100644 --- a/apollo-router/src/services/external.rs +++ b/apollo-router/src/services/external.rs @@ -20,6 +20,7 @@ use strum_macros::Display; use tower::BoxError; use tower::Service; +use super::subgraph::SubgraphRequestId; use crate::plugins::telemetry::otel::OpenTelemetrySpanExt; use crate::plugins::telemetry::reload::prepare_context; use crate::query_planner::QueryPlan; @@ -102,6 +103,8 @@ pub(crate) struct Externalizable { pub(crate) has_next: Option, #[serde(skip_serializing_if = "Option::is_none")] query_plan: Option>, + #[serde(skip_serializing_if = "Option::is_none")] + pub(crate) subgraph_request_id: Option, } #[buildstructor::buildstructor] @@ -145,6 +148,7 @@ where service_name: None, has_next: None, query_plan: None, + subgraph_request_id: None, } } @@ -184,6 +188,7 @@ where service_name: None, has_next, query_plan: None, + subgraph_request_id: None, } } @@ -224,6 +229,7 @@ where service_name: None, has_next, query_plan, + subgraph_request_id: None, } } @@ -242,6 +248,7 @@ where method: Option, service_name: Option, uri: Option, + subgraph_request_id: Option, ) -> Self { assert!(matches!( stage, @@ -263,6 +270,7 @@ where service_name, has_next: None, query_plan: None, + subgraph_request_id, } } diff --git a/apollo-router/src/services/subgraph.rs b/apollo-router/src/services/subgraph.rs index 23ebc608e3..987eef24a0 100644 --- a/apollo-router/src/services/subgraph.rs +++ b/apollo-router/src/services/subgraph.rs @@ -1,5 +1,6 @@ #![allow(missing_docs)] // FIXME +use std::fmt::Display; use std::pin::Pin; use std::sync::Arc; @@ -7,6 +8,8 @@ use apollo_compiler::validation::Valid; use http::StatusCode; use http::Version; use multimap::MultiMap; +use serde::Deserialize; +use serde::Serialize; use serde_json_bytes::ByteString; use serde_json_bytes::Map as JsonMap; use serde_json_bytes::Value; @@ -35,6 +38,15 @@ pub type BoxService = tower::util::BoxService; pub type BoxCloneService = tower::util::BoxCloneService; pub type ServiceResult = Result; pub(crate) type BoxGqlStream = Pin + Send + Sync>>; +/// unique id for a subgraph request and the related response +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct SubgraphRequestId(pub String); + +impl Display for SubgraphRequestId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0) + } +} assert_impl_all!(Request: Send); #[non_exhaustive] @@ -62,6 +74,9 @@ pub struct Request { pub(crate) authorization: Arc, pub(crate) executable_document: Option>>, + + /// unique id for this request + pub(crate) id: SubgraphRequestId, } #[buildstructor::buildstructor] @@ -90,6 +105,7 @@ impl Request { query_hash: Default::default(), authorization: Default::default(), executable_document: None, + id: SubgraphRequestId::new(), } } @@ -154,10 +170,36 @@ impl Clone for Request { query_hash: self.query_hash.clone(), authorization: self.authorization.clone(), executable_document: self.executable_document.clone(), + id: self.id.clone(), } } } +impl SubgraphRequestId { + pub fn new() -> Self { + SubgraphRequestId( + uuid::Uuid::new_v4() + .as_hyphenated() + .encode_lower(&mut uuid::Uuid::encode_buffer()) + .to_string(), + ) + } +} + +impl std::ops::Deref for SubgraphRequestId { + type Target = str; + + fn deref(&self) -> &str { + &self.0 + } +} + +impl Default for SubgraphRequestId { + fn default() -> Self { + Self::new() + } +} + assert_impl_all!(Response: Send); #[derive(Debug)] #[non_exhaustive] @@ -167,6 +209,8 @@ pub struct Response { /// Name of the subgraph, it's an Option to not introduce breaking change pub(crate) subgraph_name: Option, pub context: Context, + /// unique id matching the corresponding field in the request + pub(crate) id: SubgraphRequestId, } #[buildstructor::buildstructor] @@ -179,11 +223,13 @@ impl Response { response: http::Response, context: Context, subgraph_name: String, + id: SubgraphRequestId, ) -> Response { Self { response, context, subgraph_name: Some(subgraph_name), + id, } } @@ -202,6 +248,7 @@ impl Response { context: Context, headers: Option>, subgraph_name: Option, + id: Option, ) -> Response { // Build a response let res = graphql::Response::builder() @@ -220,10 +267,16 @@ impl Response { *response.headers_mut() = headers.unwrap_or_default(); + // Warning: the id argument for this builder is an Option to make that a non breaking change + // but this means that if a subgraph response is created explicitely without an id, it will + // be generated here and not match the id from the subgraph request + let id = id.unwrap_or_default(); + Self { response, context, subgraph_name, + id, } } @@ -244,6 +297,7 @@ impl Response { context: Option, headers: Option>, subgraph_name: Option, + id: Option, ) -> Response { Response::new( label, @@ -255,6 +309,7 @@ impl Response { context.unwrap_or_default(), headers, subgraph_name, + id, ) } @@ -276,6 +331,7 @@ impl Response { context: Option, headers: MultiMap, subgraph_name: Option, + id: Option, ) -> Result { Ok(Response::new( label, @@ -287,6 +343,7 @@ impl Response { context.unwrap_or_default(), Some(header_map(headers)?), subgraph_name, + id, )) } @@ -299,6 +356,7 @@ impl Response { status_code: Option, context: Context, subgraph_name: Option, + id: Option, ) -> Result { Ok(Response::new( Default::default(), @@ -310,6 +368,7 @@ impl Response { context, Default::default(), subgraph_name, + id, )) } } diff --git a/apollo-router/src/services/subgraph_service.rs b/apollo-router/src/services/subgraph_service.rs index 2cc367b614..8f7df0bd4c 100644 --- a/apollo-router/src/services/subgraph_service.rs +++ b/apollo-router/src/services/subgraph_service.rs @@ -44,6 +44,7 @@ use super::http::HttpClientServiceFactory; use super::http::HttpRequest; use super::layers::content_negotiation::GRAPHQL_JSON_RESPONSE_HEADER_VALUE; use super::router::body::RouterBody; +use super::subgraph::SubgraphRequestId; use super::Plugins; use crate::batching::assemble_batch; use crate::batching::BatchQuery; @@ -494,6 +495,7 @@ async fn call_websocket( subgraph_request, subscription_stream, connection_closed_signal, + id: subgraph_request_id, .. } = request; let subscription_stream_tx = @@ -707,6 +709,7 @@ async fn call_websocket( resp.map(|_| graphql::Response::default()), context, service_name, + subgraph_request_id, )) } @@ -807,7 +810,7 @@ fn http_response_to_graphql_response( pub(crate) async fn process_batch( client_factory: HttpClientServiceFactory, service: String, - mut contexts: Vec, + mut contexts: Vec<(Context, SubgraphRequestId)>, mut request: http::Request, listener_count: usize, ) -> Result, FetchError> { @@ -854,6 +857,7 @@ pub(crate) async fn process_batch( let batch_context = contexts .first() .expect("we have at least one context in the batch") + .0 .clone(); let display_body = batch_context.contains_key(LOGGING_DISPLAY_BODY); let client = client_factory.create(&service); @@ -1014,9 +1018,10 @@ pub(crate) async fn process_batch( .map(|mut http_res| { *http_res.headers_mut() = parts.headers.clone(); // Use the original context for the request to create the response - let context = contexts.pop().expect("we have a context for each response"); + let (context, id) = + contexts.pop().expect("we have a context for each response"); let resp = - SubgraphResponse::new_from_response(http_res, context, subgraph_name); + SubgraphResponse::new_from_response(http_res, context, subgraph_name, id); tracing::debug!("we have a resp: {resp:?}"); resp @@ -1098,7 +1103,12 @@ pub(crate) async fn notify_batch_query( } type BatchInfo = ( - (String, http::Request, Vec, usize), + ( + String, + http::Request, + Vec<(Context, SubgraphRequestId)>, + usize, + ), Vec>>, ); @@ -1226,7 +1236,9 @@ pub(crate) async fn call_single_http( }); let SubgraphRequest { - subgraph_request, .. + subgraph_request, + id: subgraph_request_id, + .. } = request; let operation_name = subgraph_request @@ -1357,6 +1369,7 @@ pub(crate) async fn call_single_http( .expect("it won't fail everything is coming from an existing response"), context.clone(), service_name.to_owned(), + subgraph_request_id.clone(), ); should_log = condition.lock().evaluate_response(&subgraph_response); } @@ -1401,6 +1414,7 @@ pub(crate) async fn call_single_http( resp, context, service_name.to_owned(), + subgraph_request_id, )) } diff --git a/apollo-router/src/snapshots/apollo_router__batching__tests__it_matches_subgraph_request_ids_to_responses.snap b/apollo-router/src/snapshots/apollo_router__batching__tests__it_matches_subgraph_request_ids_to_responses.snap new file mode 100644 index 0000000000..086b0189a6 --- /dev/null +++ b/apollo-router/src/snapshots/apollo_router__batching__tests__it_matches_subgraph_request_ids_to_responses.snap @@ -0,0 +1,27 @@ +--- +source: apollo-router/src/batching.rs +expression: response +--- +[ + { + "data": { + "entryA": { + "index": 0 + } + } + }, + { + "data": { + "entryA": { + "index": 1 + } + } + }, + { + "data": { + "entryA": { + "index": 2 + } + } + } +] diff --git a/apollo-router/src/test_harness.rs b/apollo-router/src/test_harness.rs index a0b5384489..516048e3d7 100644 --- a/apollo-router/src/test_harness.rs +++ b/apollo-router/src/test_harness.rs @@ -283,6 +283,7 @@ impl<'a> TestHarness<'a> { let empty_response = subgraph::Response::builder() .extensions(crate::json_ext::Object::new()) .context(request.context) + .id(request.id) .build(); std::future::ready(Ok(empty_response)) }) diff --git a/apollo-router/tests/fixtures/batching/subgraph_id.rhai b/apollo-router/tests/fixtures/batching/subgraph_id.rhai new file mode 100644 index 0000000000..e69de29bb2 diff --git a/apollo-router/tests/fixtures/batching/subgraph_id.router.yaml b/apollo-router/tests/fixtures/batching/subgraph_id.router.yaml new file mode 100644 index 0000000000..af5deda700 --- /dev/null +++ b/apollo-router/tests/fixtures/batching/subgraph_id.router.yaml @@ -0,0 +1,15 @@ +# Simple config to enable batching and rhai scripts for testing + +batching: + enabled: true + mode: batch_http_link + subgraph: + all: + enabled: true + +rhai: + scripts: ./tests/fixtures/batching + main: subgraph_id.rhai + +include_subgraph_errors: + all: true diff --git a/apollo-router/tests/fixtures/request_response_test.rhai b/apollo-router/tests/fixtures/request_response_test.rhai index 7704b0ea9a..966a1a42b0 100644 --- a/apollo-router/tests/fixtures/request_response_test.rhai +++ b/apollo-router/tests/fixtures/request_response_test.rhai @@ -99,6 +99,10 @@ fn process_subgraph_request(request) { process_common_request(true, true, request); // subgraph doesn't have a context member process_common_request(false, true, request.subgraph); + + if request.subgraph_request_id == () { + throw(`subgraph request must have a subgraph request id`); + } } fn test_response_is_primary(response) { @@ -206,6 +210,9 @@ fn process_subgraph_response(response) { process_common_response(response); test_response_body(response); test_response_status_code(response); + if response.subgraph_request_id == () { + throw(`subgraph response must have a subgraph request id`); + } } fn process_subgraph_response_om_forbidden(response) { diff --git a/apollo-router/tests/integration/redis.rs b/apollo-router/tests/integration/redis.rs index 15213ff1c4..9e6af18826 100644 --- a/apollo-router/tests/integration/redis.rs +++ b/apollo-router/tests/integration/redis.rs @@ -325,7 +325,7 @@ async fn apq() -> Result<(), BoxError> { } #[tokio::test(flavor = "multi_thread")] -async fn entity_cache() -> Result<(), BoxError> { +async fn entity_cache_basic() -> Result<(), BoxError> { if !graph_os_enabled() { return Ok(()); } diff --git a/apollo-router/tests/integration/snapshots/integration_tests__integration__redis__entity_cache-2.snap b/apollo-router/tests/integration/snapshots/integration_tests__integration__redis__entity_cache_basic-2.snap similarity index 100% rename from apollo-router/tests/integration/snapshots/integration_tests__integration__redis__entity_cache-2.snap rename to apollo-router/tests/integration/snapshots/integration_tests__integration__redis__entity_cache_basic-2.snap diff --git a/apollo-router/tests/integration/snapshots/integration_tests__integration__redis__entity_cache-3.snap b/apollo-router/tests/integration/snapshots/integration_tests__integration__redis__entity_cache_basic-3.snap similarity index 100% rename from apollo-router/tests/integration/snapshots/integration_tests__integration__redis__entity_cache-3.snap rename to apollo-router/tests/integration/snapshots/integration_tests__integration__redis__entity_cache_basic-3.snap diff --git a/apollo-router/tests/integration/snapshots/integration_tests__integration__redis__entity_cache-4.snap b/apollo-router/tests/integration/snapshots/integration_tests__integration__redis__entity_cache_basic-4.snap similarity index 100% rename from apollo-router/tests/integration/snapshots/integration_tests__integration__redis__entity_cache-4.snap rename to apollo-router/tests/integration/snapshots/integration_tests__integration__redis__entity_cache_basic-4.snap diff --git a/apollo-router/tests/integration/snapshots/integration_tests__integration__redis__entity_cache-5.snap b/apollo-router/tests/integration/snapshots/integration_tests__integration__redis__entity_cache_basic-5.snap similarity index 100% rename from apollo-router/tests/integration/snapshots/integration_tests__integration__redis__entity_cache-5.snap rename to apollo-router/tests/integration/snapshots/integration_tests__integration__redis__entity_cache_basic-5.snap diff --git a/apollo-router/tests/integration/snapshots/integration_tests__integration__redis__entity_cache.snap b/apollo-router/tests/integration/snapshots/integration_tests__integration__redis__entity_cache_basic.snap similarity index 100% rename from apollo-router/tests/integration/snapshots/integration_tests__integration__redis__entity_cache.snap rename to apollo-router/tests/integration/snapshots/integration_tests__integration__redis__entity_cache_basic.snap diff --git a/docs/shared/coproc-typical-config.mdx b/docs/shared/coproc-typical-config.mdx index a9812d47c3..5986426fd7 100644 --- a/docs/shared/coproc-typical-config.mdx +++ b/docs/shared/coproc-typical-config.mdx @@ -38,10 +38,12 @@ coprocessor: uri: false method: false service_name: false + subgraph_request_id: false response: # By including this key, the `SubgraphService` sends a coprocessor request whenever receives a subgraph response. headers: true body: false context: false service_name: false status_code: false + subgraph_request_id: false ``` diff --git a/docs/source/customizations/coprocessor.mdx b/docs/source/customizations/coprocessor.mdx index 935468ce9c..80f58855b0 100644 --- a/docs/source/customizations/coprocessor.mdx +++ b/docs/source/customizations/coprocessor.mdx @@ -504,6 +504,7 @@ Properties of the JSON body are divided into two high-level categories: "stage": "SubgraphRequest", "control": "continue", "id": "666d677225c1bc6d7c54a52b409dbd4e", + "subgraphRequestId": "b5964998b2394b64a864ef802fb5a4b3", // Data properties "headers": {}, @@ -580,6 +581,7 @@ Properties of the JSON body are divided into two high-level categories: "version": 1, "stage": "SubgraphResponse", "id": "b7810c6f7f95640fd6c6c8781e3953c0", + "subgraphRequestId": "b5964998b2394b64a864ef802fb5a4b3", "control": "continue", // Data properties @@ -758,6 +760,23 @@ A unique ID corresponding to the client request associated with this coprocessor +##### `subgraphRequestId` + +`string` + + + + +A unique ID corresponding to the subgraph request associated with this coprocessor request (only available at the `SubgraphRequest` and `SubgraphResponse` stages). + +**Do not return a _different_ value for this property.** If you do, the router treats the coprocessor request as if it failed. + + + + + + + ##### `stage` `string` diff --git a/docs/source/customizations/overview.mdx b/docs/source/customizations/overview.mdx index 74a318dbc7..18e68103c2 100644 --- a/docs/source/customizations/overview.mdx +++ b/docs/source/customizations/overview.mdx @@ -209,7 +209,7 @@ httpServer --"14. HTTP response" --> client For simplicity's sake, the preceding diagrams show the request and response sides separately and sequentially. In reality, some requests and responses may happen simultaneously and repeatedly. -For example, `SubgraphRequest`s can happen both in parallel _and_ in sequence: one subgraph's response may be necessary for another's `SubgraphRequest`. (The query planner decides which requests can happen in parallel vs. which need to happen in sequence.) +For example, `SubgraphRequest`s can happen both in parallel _and_ in sequence: one subgraph's response may be necessary for another's `SubgraphRequest`. (The query planner decides which requests can happen in parallel vs. which need to happen in sequence). To match subgraph requests to responses in customizations, the router exposes a `subgraph_request_id` field that will hold the same value in paired requests and responses. ##### Requests run in parallel diff --git a/docs/source/customizations/rhai-api.mdx b/docs/source/customizations/rhai-api.mdx index c21f39f47c..a881d3f0ff 100644 --- a/docs/source/customizations/rhai-api.mdx +++ b/docs/source/customizations/rhai-api.mdx @@ -405,6 +405,8 @@ request.subgraph.uri.path request.subgraph.uri.port ``` +**For `subgraph_service` callbacks only,** the `request` object provides the non modifiable field `request.subgraph_request_id` which is a unique ID corresponding to the subgraph request. + ### `request.context` The context is a generic key/value store that exists for the entire lifespan of a particular client request. You can use this to share information between multiple callbacks throughout the request's lifespan. @@ -594,6 +596,8 @@ response.body.extensions All of the above fields are read/write. +**For `subgraph_service` callbacks only,** the `response` object provides the non modifiable field `response.subgraph_request_id` which is a unique ID corresponding to the subgraph request, and the same id that can be obtained on the request side. + The following fields are identical in behavior to their `request` counterparts: * [`context`](#requestcontext) From 6c32fd2b8fb19ecc4b3ade2bfd09cd9ac8508992 Mon Sep 17 00:00:00 2001 From: Duckki Oe Date: Mon, 21 Oct 2024 11:13:09 -0700 Subject: [PATCH 05/77] fix(dual-query-planner): fixed a few bugs in semantic diff and literal value coercion (#6173) Coercion changes (in apollo-federation) - Fix: accept an enum value for custom scalar type (to match JS QP behavior) - Fix: coerce values in fragment definitions Semantic diff changes - Fix: The semantic diff now compares selection arguments and aliases. - Improvement: Allow integer literals to match string literals (if they are numeric) --- apollo-federation/src/compat.rs | 74 ++++++++++ .../src/query_planner/dual_query_planner.rs | 132 +++++++++++++----- apollo-router/src/query_planner/selection.rs | 11 -- 3 files changed, 170 insertions(+), 47 deletions(-) diff --git a/apollo-federation/src/compat.rs b/apollo-federation/src/compat.rs index bd571f3f5c..d3d8caa537 100644 --- a/apollo-federation/src/compat.rs +++ b/apollo-federation/src/compat.rs @@ -207,6 +207,7 @@ fn coerce_value( // Custom scalars accept any value, even objects and lists. (Value::Object(_), Some(ExtendedType::Scalar(scalar))) if !scalar.is_built_in() => {} (Value::List(_), Some(ExtendedType::Scalar(scalar))) if !scalar.is_built_in() => {} + (Value::Enum(_), Some(ExtendedType::Scalar(scalar))) if !scalar.is_built_in() => {} // Enums must match the type. (Value::Enum(value), Some(ExtendedType::Enum(enum_))) if enum_.values.contains_key(value) => {} @@ -364,6 +365,11 @@ pub(crate) fn coerce_executable_values(schema: &Valid, document: &mut Ex for operation in document.operations.named.values_mut() { coerce_operation_values(schema, operation); } + for fragment in document.fragments.values_mut() { + let fragment = fragment.make_mut(); + coerce_directive_application_values(schema, &mut fragment.directives); + coerce_selection_set_values(schema, &mut fragment.selection_set); + } } /// Applies default value coercion and removes non-semantic directives so that @@ -415,4 +421,72 @@ mod tests { } "#); } + + #[test] + fn coerces_enum_values() { + let schema = Schema::parse_and_validate( + r#" + scalar CustomScalar + type Query { + test( + string: String!, + strings: [String!]!, + custom: CustomScalar!, + customList: [CustomScalar!]!, + ): Int + } + "#, + "schema.graphql", + ) + .unwrap(); + + // Enum literals are only coerced into lists if the item type is a custom scalar type. + insta::assert_snapshot!(parse_and_coerce(&schema, r#" + { + test(string: enumVal1, strings: enumVal2, custom: enumVal1, customList: enumVal2) + } + "#), @r###" + { + test(string: enumVal1, strings: enumVal2, custom: enumVal1, customList: [enumVal2]) + } + "###); + } + + #[test] + fn coerces_in_fragment_definitions() { + let schema = Schema::parse_and_validate( + r#" + type T { + get(bools: [Boolean!]!): Int + } + type Query { + test: T + } + "#, + "schema.graphql", + ) + .unwrap(); + + insta::assert_snapshot!(parse_and_coerce(&schema, r#" + { + test { + ...f + } + } + + fragment f on T { + get(bools: true) + } + "#), @r###" + { + test { + ...f + } + } + + fragment f on T { + get(bools: [true]) + } + "###); + } } diff --git a/apollo-router/src/query_planner/dual_query_planner.rs b/apollo-router/src/query_planner/dual_query_planner.rs index 05f67d6500..c90ccb5282 100644 --- a/apollo-router/src/query_planner/dual_query_planner.rs +++ b/apollo-router/src/query_planner/dual_query_planner.rs @@ -417,6 +417,19 @@ fn vec_matches_sorted(this: &[T], other: &[T]) -> bool { } fn vec_matches_sorted_by( + this: &[T], + other: &[T], + compare: impl Fn(&T, &T) -> std::cmp::Ordering, + item_matches: impl Fn(&T, &T) -> bool, +) -> bool { + let mut this_sorted = this.to_owned(); + let mut other_sorted = other.to_owned(); + this_sorted.sort_by(&compare); + other_sorted.sort_by(&compare); + vec_matches(&this_sorted, &other_sorted, item_matches) +} + +fn vec_matches_result_sorted_by( this: &[T], other: &[T], compare: impl Fn(&T, &T) -> std::cmp::Ordering, @@ -630,17 +643,22 @@ fn hash_selection_key(selection: &Selection) -> u64 { hash_value(&get_selection_key(selection)) } +// Note: This `Selection` struct is a limited version used for the `requires` field. fn same_selection(x: &Selection, y: &Selection) -> bool { - let x_key = get_selection_key(x); - let y_key = get_selection_key(y); - if x_key != y_key { - return false; - } - let x_selections = x.selection_set(); - let y_selections = y.selection_set(); - match (x_selections, y_selections) { - (Some(x), Some(y)) => same_selection_set_sorted(x, y), - (None, None) => true, + match (x, y) { + (Selection::Field(x), Selection::Field(y)) => { + x.name == y.name + && x.alias == y.alias + && match (&x.selections, &y.selections) { + (Some(x), Some(y)) => same_selection_set_sorted(x, y), + (None, None) => true, + _ => false, + } + } + (Selection::InlineFragment(x), Selection::InlineFragment(y)) => { + x.type_condition == y.type_condition + && same_selection_set_sorted(&x.selections, &y.selections) + } _ => false, } } @@ -733,7 +751,7 @@ fn same_ast_operation_definition( ) -> Result<(), MatchFailure> { // Note: Operation names are ignored, since parallel fetches may have different names. check_match_eq!(x.operation_type, y.operation_type); - vec_matches_sorted_by( + vec_matches_result_sorted_by( &x.variables, &y.variables, |a, b| a.name.cmp(&b.name), @@ -777,6 +795,15 @@ fn ast_value_maybe_coerced_to(x: &ast::Value, y: &ast::Value) -> bool { } } + // Special case 3: JS QP may convert string to int for custom scalars, while Rust doesn't. + // - Note: This conversion seems a bit difficult to implement in the `apollo-federation`'s + // `coerce_value` function, since IntValue's constructor is private to the crate. + (ast::Value::Int(ref x), ast::Value::String(ref y)) => { + if x.as_str() == y { + return true; + } + } + // Recurse into list items. (ast::Value::List(ref x), ast::Value::List(ref y)) => { if vec_matches(x, y, |xx, yy| { @@ -829,6 +856,14 @@ fn same_ast_fragment_definition( Ok(()) } +fn same_ast_argument_value(x: &ast::Value, y: &ast::Value) -> bool { + x == y || ast_value_maybe_coerced_to(x, y) +} + +fn same_ast_argument(x: &ast::Argument, y: &ast::Argument) -> bool { + x.name == y.name && same_ast_argument_value(&x.value, &y.value) +} + fn get_ast_selection_key(selection: &ast::Selection) -> SelectionKey { match selection { ast::Selection::Field(field) => SelectionKey::Field { @@ -846,32 +881,28 @@ fn get_ast_selection_key(selection: &ast::Selection) -> SelectionKey { } } -use std::ops::Not; - -/// Get the sub-selections of a selection. -fn get_ast_selection_set(selection: &ast::Selection) -> Option<&Vec> { - match selection { - ast::Selection::Field(field) => field - .selection_set - .is_empty() - .not() - .then(|| &field.selection_set), - ast::Selection::FragmentSpread(_) => None, - ast::Selection::InlineFragment(fragment) => Some(&fragment.selection_set), - } -} - fn same_ast_selection(x: &ast::Selection, y: &ast::Selection) -> bool { - let x_key = get_ast_selection_key(x); - let y_key = get_ast_selection_key(y); - if x_key != y_key { - return false; - } - let x_selections = get_ast_selection_set(x); - let y_selections = get_ast_selection_set(y); - match (x_selections, y_selections) { - (Some(x), Some(y)) => same_ast_selection_set_sorted(x, y), - (None, None) => true, + match (x, y) { + (ast::Selection::Field(x), ast::Selection::Field(y)) => { + x.name == y.name + && x.alias == y.alias + && vec_matches_sorted_by( + &x.arguments, + &y.arguments, + |a, b| a.name.cmp(&b.name), + |a, b| same_ast_argument(a, b), + ) + && x.directives == y.directives + && same_ast_selection_set_sorted(&x.selection_set, &y.selection_set) + } + (ast::Selection::FragmentSpread(x), ast::Selection::FragmentSpread(y)) => { + x.fragment_name == y.fragment_name && x.directives == y.directives + } + (ast::Selection::InlineFragment(x), ast::Selection::InlineFragment(y)) => { + x.type_condition == y.type_condition + && x.directives == y.directives + && same_ast_selection_set_sorted(&x.selection_set, &y.selection_set) + } _ => false, } } @@ -987,6 +1018,35 @@ mod ast_comparison_tests { let ast_y = ast::Document::parse(op_y, "op_y").unwrap(); assert!(super::same_ast_document(&ast_x, &ast_y).is_ok()); } + + #[test] + fn test_selection_argument_is_compared() { + let op_x = r#"{ x(arg1: "one") }"#; + let op_y = r#"{ x(arg1: "two") }"#; + let ast_x = ast::Document::parse(op_x, "op_x").unwrap(); + let ast_y = ast::Document::parse(op_y, "op_y").unwrap(); + assert!(super::same_ast_document(&ast_x, &ast_y).is_err()); + } + + #[test] + fn test_selection_argument_order() { + let op_x = r#"{ x(arg1: "one", arg2: "two") }"#; + let op_y = r#"{ x(arg2: "two", arg1: "one") }"#; + let ast_x = ast::Document::parse(op_x, "op_x").unwrap(); + let ast_y = ast::Document::parse(op_y, "op_y").unwrap(); + assert!(super::same_ast_document(&ast_x, &ast_y).is_ok()); + } + + #[test] + fn test_string_to_id_coercion_difference() { + // JS QP coerces strings into integer for ID type, while Rust QP doesn't. + // This tests a special case that same_ast_document accepts this difference. + let op_x = r#"{ x(id: 123) }"#; + let op_y = r#"{ x(id: "123") }"#; + let ast_x = ast::Document::parse(op_x, "op_x").unwrap(); + let ast_y = ast::Document::parse(op_y, "op_y").unwrap(); + assert!(super::same_ast_document(&ast_x, &ast_y).is_ok()); + } } #[cfg(test)] diff --git a/apollo-router/src/query_planner/selection.rs b/apollo-router/src/query_planner/selection.rs index 810c1c1ac5..629b678347 100644 --- a/apollo-router/src/query_planner/selection.rs +++ b/apollo-router/src/query_planner/selection.rs @@ -23,17 +23,6 @@ pub(crate) enum Selection { InlineFragment(InlineFragment), } -impl Selection { - pub(crate) fn selection_set(&self) -> Option<&[Selection]> { - match self { - Selection::Field(Field { selections, .. }) => selections.as_deref(), - Selection::InlineFragment(InlineFragment { selections, .. }) => { - Some(selections.as_slice()) - } - } - } -} - /// The field that is used #[derive(Debug, Clone, PartialEq, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] From ed9f5048759fff8756322daef806e8ee502e09b5 Mon Sep 17 00:00:00 2001 From: Duckki Oe Date: Mon, 21 Oct 2024 20:06:20 -0700 Subject: [PATCH 06/77] fix(dual-query-planner): updated semantic diff to handle fragment name differences (#6158) - `same_ast_document` now creates a fragment mapping from the JS fragment name to matching Rust fragment name based on their definition body, not their places or names. - Fragment spreads in selection sets are compared after mapping JS fragment names to Rust fragment names. --- .../src/query_planner/dual_query_planner.rs | 144 ++++++++++++++---- 1 file changed, 117 insertions(+), 27 deletions(-) diff --git a/apollo-router/src/query_planner/dual_query_planner.rs b/apollo-router/src/query_planner/dual_query_planner.rs index c90ccb5282..fc13d7b682 100644 --- a/apollo-router/src/query_planner/dual_query_planner.rs +++ b/apollo-router/src/query_planner/dual_query_planner.rs @@ -1,6 +1,7 @@ //! Running two query planner implementations and comparing their results use std::borrow::Borrow; +use std::collections::hash_map::HashMap; use std::hash::DefaultHasher; use std::hash::Hash; use std::hash::Hasher; @@ -388,6 +389,9 @@ fn opt_plan_node_matches( } } +//================================================================================================== +// Vec comparison functions + fn vec_matches(this: &[T], other: &[T], item_matches: impl Fn(&T, &T) -> bool) -> bool { this.len() == other.len() && std::iter::zip(this, other).all(|(this, other)| item_matches(this, other)) @@ -492,6 +496,9 @@ fn vec_matches_result_as_set( Ok(()) } +//================================================================================================== +// PlanNode comparison functions + fn option_to_string(name: Option) -> String { name.map_or_else(|| "".to_string(), |name| name.to_string()) } @@ -712,7 +719,6 @@ fn same_ast_document(x: &ast::Document, y: &ast::Document) -> Result<(), MatchFa _ => others.push(def), } } - fragments.sort_by_key(|frag| frag.name.clone()); (operations, fragments, others) } @@ -726,28 +732,45 @@ fn same_ast_document(x: &ast::Document, y: &ast::Document) -> Result<(), MatchFa "Different number of operation definitions" ); + check_match_eq!(x_frags.len(), y_frags.len()); + let mut fragment_map: HashMap = HashMap::new(); + // Assumption: x_frags and y_frags are topologically sorted. + // Thus, we can build the fragment name mapping in a single pass and compare + // fragment definitions using the mapping at the same time, since earlier fragments + // will never reference later fragments. + x_frags.iter().try_fold((), |_, x_frag| { + let y_frag = y_frags + .iter() + .find(|y_frag| same_ast_fragment_definition(x_frag, y_frag, &fragment_map).is_ok()); + if let Some(y_frag) = y_frag { + if x_frag.name != y_frag.name { + // record it only if they are not identical + fragment_map.insert(x_frag.name.clone(), y_frag.name.clone()); + } + Ok(()) + } else { + Err(MatchFailure::new(format!( + "mismatch: no matching fragment definition for {}", + x_frag.name + ))) + } + })?; + check_match_eq!(x_ops.len(), y_ops.len()); x_ops .iter() .zip(y_ops.iter()) .try_fold((), |_, (x_op, y_op)| { - same_ast_operation_definition(x_op, y_op) + same_ast_operation_definition(x_op, y_op, &fragment_map) .map_err(|err| err.add_description("under operation definition")) })?; - check_match_eq!(x_frags.len(), y_frags.len()); - x_frags - .iter() - .zip(y_frags.iter()) - .try_fold((), |_, (x_frag, y_frag)| { - same_ast_fragment_definition(x_frag, y_frag) - .map_err(|err| err.add_description("under fragment definition")) - })?; Ok(()) } fn same_ast_operation_definition( x: &ast::OperationDefinition, y: &ast::OperationDefinition, + fragment_map: &HashMap, ) -> Result<(), MatchFailure> { // Note: Operation names are ignored, since parallel fetches may have different names. check_match_eq!(x.operation_type, y.operation_type); @@ -761,7 +784,8 @@ fn same_ast_operation_definition( check_match_eq!(x.directives, y.directives); check_match!(same_ast_selection_set_sorted( &x.selection_set, - &y.selection_set + &y.selection_set, + fragment_map, )); Ok(()) } @@ -845,13 +869,15 @@ fn same_variable_definition( fn same_ast_fragment_definition( x: &ast::FragmentDefinition, y: &ast::FragmentDefinition, + fragment_map: &HashMap, ) -> Result<(), MatchFailure> { - check_match_eq!(x.name, y.name); + // Note: Fragment names at definitions are ignored. check_match_eq!(x.type_condition, y.type_condition); check_match_eq!(x.directives, y.directives); check_match!(same_ast_selection_set_sorted( &x.selection_set, - &y.selection_set + &y.selection_set, + fragment_map, )); Ok(()) } @@ -864,14 +890,20 @@ fn same_ast_argument(x: &ast::Argument, y: &ast::Argument) -> bool { x.name == y.name && same_ast_argument_value(&x.value, &y.value) } -fn get_ast_selection_key(selection: &ast::Selection) -> SelectionKey { +fn get_ast_selection_key( + selection: &ast::Selection, + fragment_map: &HashMap, +) -> SelectionKey { match selection { ast::Selection::Field(field) => SelectionKey::Field { response_name: field.response_name().clone(), directives: field.directives.clone(), }, ast::Selection::FragmentSpread(fragment) => SelectionKey::FragmentSpread { - fragment_name: fragment.fragment_name.clone(), + fragment_name: fragment_map + .get(&fragment.fragment_name) + .unwrap_or(&fragment.fragment_name) + .clone(), directives: fragment.directives.clone(), }, ast::Selection::InlineFragment(fragment) => SelectionKey::InlineFragment { @@ -881,7 +913,11 @@ fn get_ast_selection_key(selection: &ast::Selection) -> SelectionKey { } } -fn same_ast_selection(x: &ast::Selection, y: &ast::Selection) -> bool { +fn same_ast_selection( + x: &ast::Selection, + y: &ast::Selection, + fragment_map: &HashMap, +) -> bool { match (x, y) { (ast::Selection::Field(x), ast::Selection::Field(y)) => { x.name == y.name @@ -893,38 +929,52 @@ fn same_ast_selection(x: &ast::Selection, y: &ast::Selection) -> bool { |a, b| same_ast_argument(a, b), ) && x.directives == y.directives - && same_ast_selection_set_sorted(&x.selection_set, &y.selection_set) + && same_ast_selection_set_sorted(&x.selection_set, &y.selection_set, fragment_map) } (ast::Selection::FragmentSpread(x), ast::Selection::FragmentSpread(y)) => { - x.fragment_name == y.fragment_name && x.directives == y.directives + let mapped_fragment_name = fragment_map + .get(&x.fragment_name) + .unwrap_or(&x.fragment_name); + *mapped_fragment_name == y.fragment_name && x.directives == y.directives } (ast::Selection::InlineFragment(x), ast::Selection::InlineFragment(y)) => { x.type_condition == y.type_condition && x.directives == y.directives - && same_ast_selection_set_sorted(&x.selection_set, &y.selection_set) + && same_ast_selection_set_sorted(&x.selection_set, &y.selection_set, fragment_map) } _ => false, } } -fn hash_ast_selection_key(selection: &ast::Selection) -> u64 { - hash_value(&get_ast_selection_key(selection)) +fn hash_ast_selection_key(selection: &ast::Selection, fragment_map: &HashMap) -> u64 { + hash_value(&get_ast_selection_key(selection, fragment_map)) } -fn same_ast_selection_set_sorted(x: &[ast::Selection], y: &[ast::Selection]) -> bool { - fn sorted_by_selection_key(s: &[ast::Selection]) -> Vec<&ast::Selection> { +// Selections are sorted and compared after renaming x's fragment spreads according to the +// fragment_map. +fn same_ast_selection_set_sorted( + x: &[ast::Selection], + y: &[ast::Selection], + fragment_map: &HashMap, +) -> bool { + fn sorted_by_selection_key<'a>( + s: &'a [ast::Selection], + fragment_map: &HashMap, + ) -> Vec<&'a ast::Selection> { let mut sorted: Vec<&ast::Selection> = s.iter().collect(); - sorted.sort_by_key(|x| hash_ast_selection_key(x)); + sorted.sort_by_key(|x| hash_ast_selection_key(x, fragment_map)); sorted } if x.len() != y.len() { return false; } - sorted_by_selection_key(x) + let x_sorted = sorted_by_selection_key(x, fragment_map); // Map fragment spreads + let y_sorted = sorted_by_selection_key(y, &Default::default()); // Don't map fragment spreads + x_sorted .into_iter() - .zip(sorted_by_selection_key(y)) - .all(|(x, y)| same_ast_selection(x, y)) + .zip(y_sorted) + .all(|(x, y)| same_ast_selection(x, y, fragment_map)) } #[cfg(test)] @@ -1047,6 +1097,46 @@ mod ast_comparison_tests { let ast_y = ast::Document::parse(op_y, "op_y").unwrap(); assert!(super::same_ast_document(&ast_x, &ast_y).is_ok()); } + + #[test] + fn test_fragment_definition_different_names() { + let op_x = r#"{ q { ...f1 ...f2 } } fragment f1 on T { x y } fragment f2 on T { w z }"#; + let op_y = r#"{ q { ...g1 ...g2 } } fragment g1 on T { x y } fragment g2 on T { w z }"#; + let ast_x = ast::Document::parse(op_x, "op_x").unwrap(); + let ast_y = ast::Document::parse(op_y, "op_y").unwrap(); + assert!(super::same_ast_document(&ast_x, &ast_y).is_ok()); + } + + #[test] + fn test_fragment_definition_different_names_nested_1() { + // Nested fragments have the same name, only top-level fragments have different names. + let op_x = r#"{ q { ...f2 } } fragment f1 on T { x y } fragment f2 on T { z ...f1 }"#; + let op_y = r#"{ q { ...g2 } } fragment f1 on T { x y } fragment g2 on T { z ...f1 }"#; + let ast_x = ast::Document::parse(op_x, "op_x").unwrap(); + let ast_y = ast::Document::parse(op_y, "op_y").unwrap(); + assert!(super::same_ast_document(&ast_x, &ast_y).is_ok()); + } + + #[test] + fn test_fragment_definition_different_names_nested_2() { + // Nested fragments have different names. + let op_x = r#"{ q { ...f2 } } fragment f1 on T { x y } fragment f2 on T { z ...f1 }"#; + let op_y = r#"{ q { ...g2 } } fragment g1 on T { x y } fragment g2 on T { z ...g1 }"#; + let ast_x = ast::Document::parse(op_x, "op_x").unwrap(); + let ast_y = ast::Document::parse(op_y, "op_y").unwrap(); + assert!(super::same_ast_document(&ast_x, &ast_y).is_ok()); + } + + #[test] + fn test_fragment_definition_different_names_nested_3() { + // Nested fragments have different names. + // Also, fragment definitions are in different order. + let op_x = r#"{ q { ...f2 ...f3 } } fragment f1 on T { x y } fragment f2 on T { z ...f1 } fragment f3 on T { w } "#; + let op_y = r#"{ q { ...g2 ...g3 } } fragment g1 on T { x y } fragment g2 on T { w } fragment g3 on T { z ...g1 }"#; + let ast_x = ast::Document::parse(op_x, "op_x").unwrap(); + let ast_y = ast::Document::parse(op_y, "op_y").unwrap(); + assert!(super::same_ast_document(&ast_x, &ast_y).is_ok()); + } } #[cfg(test)] From 990fdc84ffc537375dff07034659c4ed2cbe1b62 Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Tue, 22 Oct 2024 17:46:11 +0300 Subject: [PATCH 07/77] Add `dns_resolution_strategy` config option (#6109) Co-authored-by: Jesse Rosenberger --- .../feat_add_dns_resolution_strategy.md | 28 +++++++++++ apollo-router/src/batching.rs | 7 ++- apollo-router/src/configuration/shared/mod.rs | 19 ++++++- ...nfiguration__tests__schema_generation.snap | 49 +++++++++++++++++++ apollo-router/src/plugins/coprocessor/mod.rs | 15 +++--- .../src/plugins/traffic_shaping/mod.rs | 49 ++++++++++++++++--- apollo-router/src/router_factory.rs | 2 +- .../src/services/hickory_dns_connector.rs | 37 +++++++++++--- apollo-router/src/services/http.rs | 4 +- apollo-router/src/services/http/service.rs | 10 ++-- apollo-router/src/services/http/tests.rs | 14 ++++-- .../src/services/subgraph_service.rs | 41 ++++++++-------- docs/source/configuration/traffic-shaping.mdx | 19 +++++++ docs/source/customizations/coprocessor.mdx | 16 ++++++ 14 files changed, 248 insertions(+), 62 deletions(-) create mode 100644 .changesets/feat_add_dns_resolution_strategy.md diff --git a/.changesets/feat_add_dns_resolution_strategy.md b/.changesets/feat_add_dns_resolution_strategy.md new file mode 100644 index 0000000000..cfaa9aaf74 --- /dev/null +++ b/.changesets/feat_add_dns_resolution_strategy.md @@ -0,0 +1,28 @@ +### Add ability to configure DNS resolution strategy ([PR #6109](https://github.com/apollographql/router/pull/6109)) + +The router now supports choosing a DNS resolution strategy for the coprocessor's and subgraph's URLs. +The new option is called `dns_resolution_strategy` and supports the following values: +* `ipv4_only` - Only query for `A` (IPv4) records. +* `ipv6_only` - Only query for `AAAA` (IPv6) records. +* `ipv4_and_ipv6` - Query for both `A` (IPv4) and `AAAA` (IPv6) records in parallel. +* `ipv6_then_ipv4` - Query for `AAAA` (IPv6) records first; if that fails, query for `A` (IPv4) records. +* `ipv4_then_ipv6`(default) - Query for `A` (IPv4) records first; if that fails, query for `AAAA` (IPv6) records. + +To change the DNS resolution strategy applied to the subgraph's URL: +```yaml title="router.yaml" +traffic_shaping: + all: + dns_resolution_strategy: ipv4_then_ipv6 + +``` + +You can also change the DNS resolution strategy applied to the coprocessor's URL: +```yaml title="router.yaml" +coprocessor: + url: http://coprocessor.example.com:8081 + client: + dns_resolution_strategy: ipv4_then_ipv6 + +``` + +By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6109 diff --git a/apollo-router/src/batching.rs b/apollo-router/src/batching.rs index e8ada106a3..a66aca8d87 100644 --- a/apollo-router/src/batching.rs +++ b/apollo-router/src/batching.rs @@ -485,7 +485,6 @@ mod tests { use crate::graphql; use crate::graphql::Request; use crate::layers::ServiceExt as LayerExt; - use crate::plugins::traffic_shaping::Http2Config; use crate::query_planner::fetch::QueryHash; use crate::services::http::HttpClientServiceFactory; use crate::services::router; @@ -634,7 +633,7 @@ mod tests { let factory = HttpClientServiceFactory::from_config( "testbatch", &Configuration::default(), - Http2Config::Disable, + crate::configuration::shared::Client::default(), ); let request = SubgraphRequest::fake_builder() .subgraph_request( @@ -673,7 +672,7 @@ mod tests { let factory = HttpClientServiceFactory::from_config( "testbatch", &Configuration::default(), - Http2Config::Disable, + crate::configuration::shared::Client::default(), ); let request = SubgraphRequest::fake_builder() .subgraph_request( @@ -708,7 +707,7 @@ mod tests { let factory = HttpClientServiceFactory::from_config( "testbatch", &Configuration::default(), - Http2Config::Disable, + crate::configuration::shared::Client::default(), ); let request = SubgraphRequest::fake_builder() .subgraph_request( diff --git a/apollo-router/src/configuration/shared/mod.rs b/apollo-router/src/configuration/shared/mod.rs index 9186b65a3d..ab164ec13f 100644 --- a/apollo-router/src/configuration/shared/mod.rs +++ b/apollo-router/src/configuration/shared/mod.rs @@ -3,8 +3,25 @@ use serde::Deserialize; use crate::plugins::traffic_shaping::Http2Config; -#[derive(Debug, Clone, Default, Deserialize, JsonSchema)] +#[derive(PartialEq, Debug, Clone, Default, Deserialize, JsonSchema, buildstructor::Builder)] #[serde(deny_unknown_fields, default)] pub(crate) struct Client { pub(crate) experimental_http2: Option, + pub(crate) dns_resolution_strategy: Option, +} + +#[derive(PartialEq, Default, Debug, Clone, Copy, Deserialize, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub(crate) enum DnsResolutionStrategy { + /// Only query for `A` (IPv4) records + Ipv4Only, + /// Only query for `AAAA` (IPv6) records + Ipv6Only, + /// Query for both `A` (IPv4) and `AAAA` (IPv6) records in parallel + Ipv4AndIpv6, + /// Query for `AAAA` (IPv6) records first; if that fails, query for `A` (IPv4) records + Ipv6ThenIpv4, + #[default] + /// Default: Query for `A` (IPv4) records first; if that fails, query for `AAAA` (IPv6) records + Ipv4ThenIpv6, } 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 adccdca79a..817d67517a 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 @@ -549,6 +549,11 @@ expression: "&schema" "Client": { "additionalProperties": false, "properties": { + "dns_resolution_strategy": { + "$ref": "#/definitions/DnsResolutionStrategy", + "description": "#/definitions/DnsResolutionStrategy", + "nullable": true + }, "experimental_http2": { "$ref": "#/definitions/Http2Config", "description": "#/definitions/Http2Config", @@ -2163,6 +2168,45 @@ expression: "&schema" } ] }, + "DnsResolutionStrategy": { + "oneOf": [ + { + "description": "Only query for `A` (IPv4) records", + "enum": [ + "ipv4_only" + ], + "type": "string" + }, + { + "description": "Only query for `AAAA` (IPv6) records", + "enum": [ + "ipv6_only" + ], + "type": "string" + }, + { + "description": "Query for both `A` (IPv4) and `AAAA` (IPv6) records in parallel", + "enum": [ + "ipv4_and_ipv6" + ], + "type": "string" + }, + { + "description": "Query for `AAAA` (IPv6) records first; if that fails, query for `A` (IPv4) records", + "enum": [ + "ipv6_then_ipv4" + ], + "type": "string" + }, + { + "description": "Default: Query for `A` (IPv4) records first; if that fails, query for `AAAA` (IPv6) records", + "enum": [ + "ipv4_then_ipv6" + ], + "type": "string" + } + ] + }, "Enabled": { "enum": [ "enabled" @@ -6405,6 +6449,11 @@ expression: "&schema" "nullable": true, "type": "boolean" }, + "dns_resolution_strategy": { + "$ref": "#/definitions/DnsResolutionStrategy", + "description": "#/definitions/DnsResolutionStrategy", + "nullable": true + }, "experimental_http2": { "$ref": "#/definitions/Http2Config", "description": "#/definitions/Http2Config", diff --git a/apollo-router/src/plugins/coprocessor/mod.rs b/apollo-router/src/plugins/coprocessor/mod.rs index e979776c8a..cbc5b88213 100644 --- a/apollo-router/src/plugins/coprocessor/mod.rs +++ b/apollo-router/src/plugins/coprocessor/mod.rs @@ -78,7 +78,9 @@ impl Plugin for CoprocessorPlugin { type Config = Conf; async fn new(init: PluginInit) -> Result { - let mut http_connector = new_async_http_connector()?; + let client_config = init.config.client.clone().unwrap_or_default(); + let mut http_connector = + new_async_http_connector(client_config.dns_resolution_strategy.unwrap_or_default())?; http_connector.set_nodelay(true); http_connector.set_keepalive(Some(std::time::Duration::from_secs(60))); http_connector.enforce_http(false); @@ -93,9 +95,8 @@ impl Plugin for CoprocessorPlugin { .https_or_http() .enable_http1(); - let connector = if init.config.client.is_none() - || init.config.client.as_ref().unwrap().experimental_http2 != Some(Http2Config::Disable) - { + let experimental_http2 = client_config.experimental_http2.unwrap_or_default(); + let connector = if experimental_http2 != Http2Config::Disable { builder.enable_http2().wrap_connector(http_connector) } else { builder.wrap_connector(http_connector) @@ -106,11 +107,7 @@ impl Plugin for CoprocessorPlugin { .layer(TimeoutLayer::new(init.config.timeout)) .service( hyper::Client::builder() - .http2_only( - init.config.client.is_some() - && init.config.client.as_ref().unwrap().experimental_http2 - == Some(Http2Config::Http2Only), - ) + .http2_only(experimental_http2 == Http2Config::Http2Only) .pool_idle_timeout(POOL_IDLE_TIMEOUT_DURATION) .build(connector), ), diff --git a/apollo-router/src/plugins/traffic_shaping/mod.rs b/apollo-router/src/plugins/traffic_shaping/mod.rs index e77322fffa..1125239d10 100644 --- a/apollo-router/src/plugins/traffic_shaping/mod.rs +++ b/apollo-router/src/plugins/traffic_shaping/mod.rs @@ -35,6 +35,7 @@ use self::rate::RateLimited; pub(crate) use self::retry::RetryPolicy; use self::timeout::Elapsed; use self::timeout::TimeoutLayer; +use crate::configuration::shared::DnsResolutionStrategy; use crate::error::ConfigurationError; use crate::graphql; use crate::layers::ServiceBuilderExt; @@ -72,6 +73,8 @@ struct Shaping { experimental_retry: Option, /// Enable HTTP2 for subgraphs experimental_http2: Option, + /// DNS resolution strategy for subgraphs + dns_resolution_strategy: Option, } #[derive(PartialEq, Default, Debug, Clone, Deserialize, JsonSchema)] @@ -109,6 +112,11 @@ impl Merge for Shaping { .as_ref() .or(fallback.experimental_http2.as_ref()) .cloned(), + dns_resolution_strategy: self + .dns_resolution_strategy + .as_ref() + .or(fallback.dns_resolution_strategy.as_ref()) + .cloned(), }, } } @@ -444,13 +452,19 @@ impl TrafficShaping { } } - pub(crate) fn enable_subgraph_http2(&self, service_name: &str) -> Http2Config { + pub(crate) fn subgraph_client_config( + &self, + service_name: &str, + ) -> crate::configuration::shared::Client { Self::merge_config( self.config.all.as_ref(), self.config.subgraphs.get(service_name), ) - .and_then(|config| config.shaping.experimental_http2) - .unwrap_or(Http2Config::Enable) + .map(|config| crate::configuration::shared::Client { + experimental_http2: config.shaping.experimental_http2, + dns_resolution_strategy: config.shaping.dns_resolution_strategy, + }) + .unwrap_or_default() } } @@ -749,16 +763,19 @@ mod test { } #[tokio::test] - async fn test_enable_subgraph_http2() { + async fn test_subgraph_client_config() { let config = serde_yaml::from_str::( r#" all: experimental_http2: disable + dns_resolution_strategy: ipv6_only subgraphs: products: experimental_http2: enable + dns_resolution_strategy: ipv6_then_ipv4 reviews: experimental_http2: disable + dns_resolution_strategy: ipv4_only router: timeout: 65s "#, @@ -769,9 +786,27 @@ mod test { .await .unwrap(); - assert!(shaping_config.enable_subgraph_http2("products") == Http2Config::Enable); - assert!(shaping_config.enable_subgraph_http2("reviews") == Http2Config::Disable); - assert!(shaping_config.enable_subgraph_http2("this_doesnt_exist") == Http2Config::Disable); + assert_eq!( + shaping_config.subgraph_client_config("products"), + crate::configuration::shared::Client { + experimental_http2: Some(Http2Config::Enable), + dns_resolution_strategy: Some(DnsResolutionStrategy::Ipv6ThenIpv4), + }, + ); + assert_eq!( + shaping_config.subgraph_client_config("reviews"), + crate::configuration::shared::Client { + experimental_http2: Some(Http2Config::Disable), + dns_resolution_strategy: Some(DnsResolutionStrategy::Ipv4Only), + }, + ); + assert_eq!( + shaping_config.subgraph_client_config("this_doesnt_exist"), + crate::configuration::shared::Client { + experimental_http2: Some(Http2Config::Disable), + dns_resolution_strategy: Some(DnsResolutionStrategy::Ipv6Only), + }, + ); } #[tokio::test(flavor = "multi_thread")] diff --git a/apollo-router/src/router_factory.rs b/apollo-router/src/router_factory.rs index b7a894e31e..ca40bd0a86 100644 --- a/apollo-router/src/router_factory.rs +++ b/apollo-router/src/router_factory.rs @@ -417,7 +417,7 @@ pub(crate) async fn create_subgraph_services( name, configuration, &tls_root_store, - shaping.enable_subgraph_http2(name), + shaping.subgraph_client_config(name), )?; let http_service_factory = HttpClientServiceFactory::new(http_service, plugins.clone()); diff --git a/apollo-router/src/services/hickory_dns_connector.rs b/apollo-router/src/services/hickory_dns_connector.rs index 70e26ab497..987c6ec52f 100644 --- a/apollo-router/src/services/hickory_dns_connector.rs +++ b/apollo-router/src/services/hickory_dns_connector.rs @@ -6,13 +6,17 @@ use std::pin::Pin; use std::task::Context; use std::task::Poll; +use hickory_resolver::config::LookupIpStrategy; +use hickory_resolver::system_conf::read_system_conf; use hickory_resolver::TokioAsyncResolver; use hyper::client::connect::dns::Name; use hyper::client::HttpConnector; use hyper::service::Service; +use crate::configuration::shared::DnsResolutionStrategy; + /// Wrapper around hickory-resolver's -/// [`TokioAsyncResolver`](https://docs.rs/hickory-resolver/latest/hickory_resolver/type.TokioAsyncResolver.html) +/// [`TokioAsyncResolver`](https://docs.rs/hickory-resolver/0.24.1/hickory_resolver/type.TokioAsyncResolver.html) /// /// The resolver runs a background Task which manages dns requests. When a new resolver is created, /// the background task is also created, it needs to be spawned on top of an executor before using the client, @@ -21,11 +25,14 @@ use hyper::service::Service; pub(crate) struct AsyncHyperResolver(TokioAsyncResolver); impl AsyncHyperResolver { - /// constructs a new resolver from default configuration, uses the corresponding method of - /// [`TokioAsyncResolver`](https://docs.rs/hickory-resolver/latest/hickory_resolver/type.TokioAsyncResolver.html) - pub(crate) fn new_from_system_conf() -> Result { - let resolver = TokioAsyncResolver::tokio_from_system_conf()?; - Ok(Self(resolver)) + /// constructs a new resolver from default configuration, using [read_system_conf](https://docs.rs/hickory-resolver/0.24.1/hickory_resolver/system_conf/fn.read_system_conf.html) + fn new_from_system_conf( + dns_resolution_strategy: DnsResolutionStrategy, + ) -> Result { + let (config, mut options) = read_system_conf()?; + options.ip_strategy = dns_resolution_strategy.into(); + + Ok(Self(TokioAsyncResolver::tokio(config, options))) } } @@ -56,8 +63,22 @@ impl Service for AsyncHyperResolver { } } +impl From for LookupIpStrategy { + fn from(value: DnsResolutionStrategy) -> LookupIpStrategy { + match value { + DnsResolutionStrategy::Ipv4Only => LookupIpStrategy::Ipv4Only, + DnsResolutionStrategy::Ipv6Only => LookupIpStrategy::Ipv6Only, + DnsResolutionStrategy::Ipv4AndIpv6 => LookupIpStrategy::Ipv4AndIpv6, + DnsResolutionStrategy::Ipv6ThenIpv4 => LookupIpStrategy::Ipv6thenIpv4, + DnsResolutionStrategy::Ipv4ThenIpv6 => LookupIpStrategy::Ipv4thenIpv6, + } + } +} + /// A helper function to create an http connector and a dns task with the default configuration -pub(crate) fn new_async_http_connector() -> Result, io::Error> { - let resolver = AsyncHyperResolver::new_from_system_conf()?; +pub(crate) fn new_async_http_connector( + dns_resolution_strategy: DnsResolutionStrategy, +) -> Result, io::Error> { + let resolver = AsyncHyperResolver::new_from_system_conf(dns_resolution_strategy)?; Ok(HttpConnector::new_with_resolver(resolver)) } diff --git a/apollo-router/src/services/http.rs b/apollo-router/src/services/http.rs index 7f5d782498..105bb26065 100644 --- a/apollo-router/src/services/http.rs +++ b/apollo-router/src/services/http.rs @@ -47,7 +47,7 @@ impl HttpClientServiceFactory { pub(crate) fn from_config( service: impl Into, configuration: &crate::Configuration, - http2: crate::plugins::traffic_shaping::Http2Config, + client_config: crate::configuration::shared::Client, ) -> Self { use indexmap::IndexMap; @@ -55,7 +55,7 @@ impl HttpClientServiceFactory { service, configuration, &rustls::RootCertStore::empty(), - http2, + client_config, ) .unwrap(); diff --git a/apollo-router/src/services/http/service.rs b/apollo-router/src/services/http/service.rs index 05e93ca5de..d629412f0c 100644 --- a/apollo-router/src/services/http/service.rs +++ b/apollo-router/src/services/http/service.rs @@ -103,7 +103,7 @@ impl HttpClientService { service: impl Into, configuration: &Configuration, tls_root_store: &RootCertStore, - http2: Http2Config, + client_config: crate::configuration::shared::Client, ) -> Result { let name: String = service.into(); let tls_cert_store = configuration @@ -131,15 +131,16 @@ impl HttpClientService { let tls_client_config = generate_tls_client_config(tls_cert_store, client_cert_config)?; - HttpClientService::new(name, http2, tls_client_config) + HttpClientService::new(name, tls_client_config, client_config) } pub(crate) fn new( service: impl Into, - http2: Http2Config, tls_config: ClientConfig, + client_config: crate::configuration::shared::Client, ) -> Result { - let mut http_connector = new_async_http_connector()?; + let mut http_connector = + new_async_http_connector(client_config.dns_resolution_strategy.unwrap_or_default())?; http_connector.set_nodelay(true); http_connector.set_keepalive(Some(std::time::Duration::from_secs(60))); http_connector.enforce_http(false); @@ -149,6 +150,7 @@ impl HttpClientService { .https_or_http() .enable_http1(); + let http2 = client_config.experimental_http2.unwrap_or_default(); let connector = if http2 != Http2Config::Disable { builder.enable_http2().wrap_connector(http_connector) } else { diff --git a/apollo-router/src/services/http/tests.rs b/apollo-router/src/services/http/tests.rs index 892dc30e1b..68bf996939 100644 --- a/apollo-router/src/services/http/tests.rs +++ b/apollo-router/src/services/http/tests.rs @@ -116,7 +116,7 @@ async fn tls_self_signed() { "test", &config, &rustls::RootCertStore::empty(), - Http2Config::Enable, + crate::configuration::shared::Client::default(), ) .unwrap(); @@ -173,7 +173,7 @@ async fn tls_custom_root() { "test", &config, &rustls::RootCertStore::empty(), - Http2Config::Enable, + crate::configuration::shared::Client::default(), ) .unwrap(); @@ -283,7 +283,7 @@ async fn tls_client_auth() { "test", &config, &rustls::RootCertStore::empty(), - Http2Config::Enable, + crate::configuration::shared::Client::default(), ) .unwrap(); @@ -343,11 +343,13 @@ async fn test_subgraph_h2c() { tokio::task::spawn(emulate_h2c_server(listener)); let subgraph_service = HttpClientService::new( "test", - Http2Config::Http2Only, rustls::ClientConfig::builder() .with_safe_defaults() .with_native_roots() .with_no_client_auth(), + crate::configuration::shared::Client::builder() + .experimental_http2(Http2Config::Http2Only) + .build(), ) .expect("can create a HttpService"); @@ -419,11 +421,13 @@ async fn test_compressed_request_response_body() { tokio::task::spawn(emulate_subgraph_compressed_response(listener)); let subgraph_service = HttpClientService::new( "test", - Http2Config::Http2Only, rustls::ClientConfig::builder() .with_safe_defaults() .with_native_roots() .with_no_client_auth(), + crate::configuration::shared::Client::builder() + .experimental_http2(Http2Config::Http2Only) + .build(), ) .expect("can create a HttpService"); diff --git a/apollo-router/src/services/subgraph_service.rs b/apollo-router/src/services/subgraph_service.rs index 8f7df0bd4c..9dbb9fb773 100644 --- a/apollo-router/src/services/subgraph_service.rs +++ b/apollo-router/src/services/subgraph_service.rs @@ -1713,7 +1713,6 @@ mod tests { use crate::plugins::subscription::SubgraphPassthroughMode; use crate::plugins::subscription::SubscriptionModeConfig; use crate::plugins::subscription::SUBSCRIPTION_CALLBACK_HMAC_KEY; - use crate::plugins::traffic_shaping::Http2Config; use crate::protocols::websocket::ClientMessage; use crate::protocols::websocket::ServerMessage; use crate::protocols::websocket::WebSocketProtocol; @@ -2390,7 +2389,7 @@ mod tests { HttpClientServiceFactory::from_config( "testbis", &Configuration::default(), - Http2Config::Disable, + crate::configuration::shared::Client::default(), ), ) .expect("can create a SubgraphService"); @@ -2434,7 +2433,7 @@ mod tests { HttpClientServiceFactory::from_config( "test", &Configuration::default(), - Http2Config::Enable, + crate::configuration::shared::Client::default(), ), ) .expect("can create a SubgraphService"); @@ -2468,7 +2467,7 @@ mod tests { HttpClientServiceFactory::from_config( "test", &Configuration::default(), - Http2Config::Enable, + crate::configuration::shared::Client::default(), ), ) .expect("can create a SubgraphService"); @@ -2503,7 +2502,7 @@ mod tests { HttpClientServiceFactory::from_config( "test", &Configuration::default(), - Http2Config::Enable, + crate::configuration::shared::Client::default(), ), ) .expect("can create a SubgraphService"); @@ -2541,7 +2540,7 @@ mod tests { HttpClientServiceFactory::from_config( "test", &Configuration::default(), - Http2Config::Enable, + crate::configuration::shared::Client::default(), ), ) .expect("can create a SubgraphService"); @@ -2580,7 +2579,7 @@ mod tests { HttpClientServiceFactory::from_config( "test", &Configuration::default(), - Http2Config::Enable, + crate::configuration::shared::Client::default(), ), ) .expect("can create a SubgraphService"); @@ -2623,7 +2622,7 @@ mod tests { HttpClientServiceFactory::from_config( "test", &Configuration::default(), - Http2Config::Enable, + crate::configuration::shared::Client::default(), ), ) .expect("can create a SubgraphService"); @@ -2664,7 +2663,7 @@ mod tests { HttpClientServiceFactory::from_config( "test", &Configuration::default(), - Http2Config::Enable, + crate::configuration::shared::Client::default(), ), ) .expect("can create a SubgraphService"); @@ -2717,7 +2716,7 @@ mod tests { HttpClientServiceFactory::from_config( "test", &Configuration::default(), - Http2Config::Enable, + crate::configuration::shared::Client::default(), ), ) .expect("can create a SubgraphService"); @@ -2761,7 +2760,7 @@ mod tests { HttpClientServiceFactory::from_config( "test", &Configuration::default(), - Http2Config::Enable, + crate::configuration::shared::Client::default(), ), ) .expect("can create a SubgraphService"); @@ -2803,7 +2802,7 @@ mod tests { HttpClientServiceFactory::from_config( "test", &Configuration::default(), - Http2Config::Enable, + crate::configuration::shared::Client::default(), ), ) .expect("can create a SubgraphService"); @@ -2841,7 +2840,7 @@ mod tests { HttpClientServiceFactory::from_config( "test", &Configuration::default(), - Http2Config::Enable, + crate::configuration::shared::Client::default(), ), ) .expect("can create a SubgraphService"); @@ -2879,7 +2878,7 @@ mod tests { HttpClientServiceFactory::from_config( "test", &Configuration::default(), - Http2Config::Enable, + crate::configuration::shared::Client::default(), ), ) .expect("can create a SubgraphService"); @@ -2916,7 +2915,7 @@ mod tests { HttpClientServiceFactory::from_config( "test", &Configuration::default(), - Http2Config::Enable, + crate::configuration::shared::Client::default(), ), ) .expect("can create a SubgraphService"); @@ -2953,7 +2952,7 @@ mod tests { HttpClientServiceFactory::from_config( "test", &Configuration::default(), - Http2Config::Enable, + crate::configuration::shared::Client::default(), ), ) .expect("can create a SubgraphService"); @@ -2999,7 +2998,7 @@ mod tests { HttpClientServiceFactory::from_config( "test", &Configuration::default(), - Http2Config::Enable, + crate::configuration::shared::Client::default(), ), ) .expect("can create a SubgraphService"); @@ -3043,7 +3042,7 @@ mod tests { HttpClientServiceFactory::from_config( "test", &Configuration::default(), - Http2Config::Enable, + crate::configuration::shared::Client::default(), ), ) .expect("can create a SubgraphService"); @@ -3084,7 +3083,7 @@ mod tests { HttpClientServiceFactory::from_config( "test", &Configuration::default(), - Http2Config::Enable, + crate::configuration::shared::Client::default(), ), ) .expect("can create a SubgraphService"); @@ -3125,7 +3124,7 @@ mod tests { HttpClientServiceFactory::from_config( "test", &Configuration::default(), - Http2Config::Enable, + crate::configuration::shared::Client::default(), ), ) .expect("can create a SubgraphService"); @@ -3166,7 +3165,7 @@ mod tests { HttpClientServiceFactory::from_config( "test", &Configuration::default(), - Http2Config::Enable, + crate::configuration::shared::Client::default(), ), ) .expect("can create a SubgraphService"); diff --git a/docs/source/configuration/traffic-shaping.mdx b/docs/source/configuration/traffic-shaping.mdx index c6d027fbca..adfbe3f8ad 100644 --- a/docs/source/configuration/traffic-shaping.mdx +++ b/docs/source/configuration/traffic-shaping.mdx @@ -34,6 +34,7 @@ traffic_shaping: retry_percent: 0.2 # defines the proportion of available retries to the current number of tokens retry_mutations: false # allows retries on mutations. This should only be enabled if mutations are idempotent experimental_http2: enable # Configures HTTP/2 usage. Can be 'enable' (default), 'disable' or 'http2only' + dns_resolution_strategy: ipv4_then_ipv6 # Changes DNS resolution strategy for subgraph. ``` ### Preset values @@ -42,6 +43,7 @@ The preset values of `traffic_shaping` that's enabled by default: - `timeout: 30s` for all timeouts - `experimental_http2: enable` +- `dns_resolution_strategy: ipv4_then_ipv6` ## Client side traffic shaping @@ -186,6 +188,23 @@ traffic_shaping: +### DNS resolution strategy + +You can also change DNS resolution strategy applied to subgraphs's URL: +```yaml title="router.yaml" +traffic_shaping: + all: + dns_resolution_strategy: ipv4_then_ipv6 + +``` + +Possible strategies are: +* `ipv4_only` - Only query for `A` (IPv4) records. +* `ipv6_only` - Only query for `AAAA` (IPv6) records. +* `ipv4_and_ipv6` - Query for both `A` (IPv4) and `AAAA` (IPv6) records in parallel. +* `ipv6_then_ipv4` - Query for `AAAA` (IPv6) records first; if that fails, query for `A` (IPv4) records. +* `ipv4_then_ipv6`(default) - Query for `A` (IPv4) records first; if that fails, query for `AAAA` (IPv6) records. + ### Ordering Traffic shaping always executes these steps in the same order, to ensure a consistent behaviour. Declaration order in the configuration will not affect the runtime order: diff --git a/docs/source/customizations/coprocessor.mdx b/docs/source/customizations/coprocessor.mdx index 80f58855b0..050fc2de06 100644 --- a/docs/source/customizations/coprocessor.mdx +++ b/docs/source/customizations/coprocessor.mdx @@ -152,6 +152,22 @@ coprocessor: ``` +You can also change DNS resolution strategy applied to coprocessor's URL: +```yaml title="router.yaml" +coprocessor: + url: http://coprocessor.example.com:8081 + client: + dns_resolution_strategy: ipv4_then_ipv6 + +``` + +Possible strategies are: +* `ipv4_only` - Only query for `A` (IPv4) records. +* `ipv6_only` - Only query for `AAAA` (IPv6) records. +* `ipv4_and_ipv6` - Query for both `A` (IPv4) and `AAAA` (IPv6) records in parallel. +* `ipv6_then_ipv4` - Query for `AAAA` (IPv6) records first; if that fails, query for `A` (IPv4) records. +* `ipv4_then_ipv6`(default) - Query for `A` (IPv4) records first; if that fails, query for `AAAA` (IPv6) records. + ## Coprocessor request format The router communicates with your coprocessor via HTTP POST requests (called **coprocessor requests**). The body of each coprocessor request is a JSON object with properties that describe either the current client request or the current router response. From 79b0acad8992750a951ae30d7f23c8d7b5c3e315 Mon Sep 17 00:00:00 2001 From: Duckki Oe Date: Wed, 23 Oct 2024 11:24:11 -0700 Subject: [PATCH 08/77] test(dual-query-planner): improved semantic diff message for parallel nodes (#6182) --- .../src/query_planner/dual_query_planner.rs | 136 +++++++++++++++--- 1 file changed, 120 insertions(+), 16 deletions(-) diff --git a/apollo-router/src/query_planner/dual_query_planner.rs b/apollo-router/src/query_planner/dual_query_planner.rs index fc13d7b682..5c0f41846f 100644 --- a/apollo-router/src/query_planner/dual_query_planner.rs +++ b/apollo-router/src/query_planner/dual_query_planner.rs @@ -2,6 +2,7 @@ use std::borrow::Borrow; use std::collections::hash_map::HashMap; +use std::fmt::Write; use std::hash::DefaultHasher; use std::hash::Hash; use std::hash::Hasher; @@ -465,35 +466,138 @@ fn vec_matches_as_set(this: &[T], other: &[T], item_matches: impl Fn(&T, &T) && vec_includes_as_set(other, this, &item_matches) } -fn vec_matches_result_as_set( +// Forward/reverse mappings from one Vec items (indices) to another. +type VecMapping = (HashMap, HashMap); + +// performs a set comparison, ignoring order +// and returns a mapping from `this` to `other`. +fn vec_matches_as_set_with_mapping( this: &[T], other: &[T], item_matches: impl Fn(&T, &T) -> bool, -) -> Result<(), MatchFailure> { +) -> VecMapping { // Set-inclusion test in both directions - check_match_eq!(this.len(), other.len()); - for (index, this_node) in this.iter().enumerate() { - if !other + // - record forward/reverse mapping from this items <-> other items for reporting mismatches + let mut forward_map: HashMap = HashMap::new(); + let mut reverse_map: HashMap = HashMap::new(); + for (this_pos, this_node) in this.iter().enumerate() { + if let Some(other_pos) = other .iter() - .any(|other_node| item_matches(this_node, other_node)) + .position(|other_node| item_matches(this_node, other_node)) { - return Err(MatchFailure::new(format!( - "mismatched set: missing item[{}]", - index - ))); + forward_map.insert(this_pos, other_pos); + reverse_map.insert(other_pos, this_pos); } } - for other_node in other.iter() { - if !this + for (other_pos, other_node) in other.iter().enumerate() { + if reverse_map.contains_key(&other_pos) { + continue; + } + if let Some(this_pos) = this .iter() - .any(|this_node| item_matches(this_node, other_node)) + .position(|this_node| item_matches(this_node, other_node)) { + forward_map.insert(this_pos, other_pos); + reverse_map.insert(other_pos, this_pos); + } + } + (forward_map, reverse_map) +} + +// Returns a formatted mismatch message and an optional pair of mismatched positions if the pair +// are the only remaining unmatched items. +fn format_mismatch_as_set( + this_len: usize, + other_len: usize, + forward_map: &HashMap, + reverse_map: &HashMap, +) -> Result<(String, Option<(usize, usize)>), std::fmt::Error> { + let mut ret = String::new(); + let buf = &mut ret; + write!(buf, "- mapping from left to right: [")?; + let mut this_missing_pos = None; + for this_pos in 0..this_len { + if this_pos != 0 { + write!(buf, ", ")?; + } + if let Some(other_pos) = forward_map.get(&this_pos) { + write!(buf, "{}", other_pos)?; + } else { + this_missing_pos = Some(this_pos); + write!(buf, "?")?; + } + } + writeln!(buf, "]")?; + + write!(buf, "- left-over on the right: [")?; + let mut other_missing_count = 0; + let mut other_missing_pos = None; + for other_pos in 0..other_len { + if reverse_map.get(&other_pos).is_none() { + if other_missing_count != 0 { + write!(buf, ", ")?; + } + other_missing_count += 1; + other_missing_pos = Some(other_pos); + write!(buf, "{}", other_pos)?; + } + } + write!(buf, "]")?; + let unmatched_pair = if let (Some(this_missing_pos), Some(other_missing_pos)) = + (this_missing_pos, other_missing_pos) + { + if this_len == 1 + forward_map.len() && other_len == 1 + reverse_map.len() { + // Special case: There are only one missing item on each side. They are supposed to + // match each other. + Some((this_missing_pos, other_missing_pos)) + } else { + None + } + } else { + None + }; + Ok((ret, unmatched_pair)) +} + +fn vec_matches_result_as_set( + this: &[T], + other: &[T], + item_matches: impl Fn(&T, &T) -> Result<(), MatchFailure>, +) -> Result { + // Set-inclusion test in both directions + // - record forward/reverse mapping from this items <-> other items for reporting mismatches + let (forward_map, reverse_map) = + vec_matches_as_set_with_mapping(this, other, |a, b| item_matches(a, b).is_ok()); + if forward_map.len() == this.len() && reverse_map.len() == other.len() { + Ok((forward_map, reverse_map)) + } else { + // report mismatch + let Ok((message, unmatched_pair)) = + format_mismatch_as_set(this.len(), other.len(), &forward_map, &reverse_map) + else { + // Exception: Unable to format mismatch report => fallback to most generic message return Err(MatchFailure::new( - "mismatched set: extra item found".to_string(), + "mismatch at vec_matches_result_as_set (failed to format mismatched sets)" + .to_string(), )); + }; + if let Some(unmatched_pair) = unmatched_pair { + // found a unique pair to report => use that pair's error message + let Err(err) = item_matches(&this[unmatched_pair.0], &other[unmatched_pair.1]) else { + // Exception: Unable to format unique pair mismatch error => fallback to overall report + return Err(MatchFailure::new(format!( + "mismatched sets (failed to format unique pair mismatch error):\n{}", + message + ))); + }; + Err(err.add_description(&format!( + "under a sole unmatched pair ({} -> {}) in a set comparison", + unmatched_pair.0, unmatched_pair.1 + ))) + } else { + Err(MatchFailure::new(format!("mismatched sets:\n{}", message))) } } - Ok(()) } //================================================================================================== @@ -510,7 +614,7 @@ fn plan_node_matches(this: &PlanNode, other: &PlanNode) -> Result<(), MatchFailu .map_err(|err| err.add_description("under Sequence node"))?; } (PlanNode::Parallel { nodes: this }, PlanNode::Parallel { nodes: other }) => { - vec_matches_result_as_set(this, other, |a, b| plan_node_matches(a, b).is_ok()) + vec_matches_result_as_set(this, other, plan_node_matches) .map_err(|err| err.add_description("under Parallel node"))?; } (PlanNode::Fetch(this), PlanNode::Fetch(other)) => { From 17d90ebc7db6aa8b8cd60256a1d9664e6aeb4c0a Mon Sep 17 00:00:00 2001 From: Taylor Ninesling Date: Fri, 25 Oct 2024 09:01:08 -0700 Subject: [PATCH 09/77] Remove unnecessary warn logs from ResponseVisitor (#6192) --- .../fix_tninesling_remove_demand_control_warnings.md | 5 +++++ apollo-router/src/graphql/visitor.rs | 7 ------- 2 files changed, 5 insertions(+), 7 deletions(-) create mode 100644 .changesets/fix_tninesling_remove_demand_control_warnings.md diff --git a/.changesets/fix_tninesling_remove_demand_control_warnings.md b/.changesets/fix_tninesling_remove_demand_control_warnings.md new file mode 100644 index 0000000000..195ad7d04c --- /dev/null +++ b/.changesets/fix_tninesling_remove_demand_control_warnings.md @@ -0,0 +1,5 @@ +### Remove noisy demand control logs ([PR #6192](https://github.com/apollographql/router/pull/6192)) + +Demand control no longer logs warnings when a subgraph response is missing a requested field. + +By [@tninesling](https://github.com/tninesling) in https://github.com/apollographql/router/pull/6192 diff --git a/apollo-router/src/graphql/visitor.rs b/apollo-router/src/graphql/visitor.rs index b344393821..aa901508db 100644 --- a/apollo-router/src/graphql/visitor.rs +++ b/apollo-router/src/graphql/visitor.rs @@ -92,18 +92,11 @@ pub(crate) trait ResponseVisitor { inner_field.as_ref(), value, ); - } else { - tracing::warn!("The response did not include a field corresponding to query field {:?}", inner_field); } } apollo_compiler::executable::Selection::FragmentSpread(fragment_spread) => { if let Some(fragment) = fragment_spread.fragment_def(request) { self.visit_selections(request, variables, &fragment.selection_set, fields); - } else { - tracing::warn!( - "The fragment {} was not found in the query document.", - fragment_spread.fragment_name - ); } } apollo_compiler::executable::Selection::InlineFragment(inline_fragment) => { From b49acf3e0cca4866e3aa71eeb2cbedaaa4c8ec3e Mon Sep 17 00:00:00 2001 From: Duckki Oe Date: Fri, 25 Oct 2024 11:53:09 -0700 Subject: [PATCH 10/77] test(federation): snapshot logging improvements for `FetchDependencyGraph` and open/closed branches (#6190) --- .../src/query_graph/graph_path.rs | 6 + .../src/query_plan/fetch_dependency_graph.rs | 12 +- .../src/query_plan/query_planner.rs | 31 +++-- .../query_plan/query_planning_traversal.rs | 115 ++++++++++++++---- apollo-federation/src/utils/logging.rs | 91 ++++++++++++-- 5 files changed, 204 insertions(+), 51 deletions(-) diff --git a/apollo-federation/src/query_graph/graph_path.rs b/apollo-federation/src/query_graph/graph_path.rs index 7c9fe75827..da06fffcdf 100644 --- a/apollo-federation/src/query_graph/graph_path.rs +++ b/apollo-federation/src/query_graph/graph_path.rs @@ -591,6 +591,12 @@ pub(crate) struct SimultaneousPathsWithLazyIndirectPaths { pub(crate) lazily_computed_indirect_paths: Vec>, } +impl Display for SimultaneousPathsWithLazyIndirectPaths { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.paths) + } +} + /// A "set" of excluded destinations (i.e. subgraph names). Note that we use a `Vec` instead of set /// because this is used in pretty hot paths (the whole path computation is CPU intensive) and will /// basically always be tiny (it's bounded by the number of distinct key on a given type, so usually diff --git a/apollo-federation/src/query_plan/fetch_dependency_graph.rs b/apollo-federation/src/query_plan/fetch_dependency_graph.rs index f31bd0d2ff..5629183fd5 100644 --- a/apollo-federation/src/query_plan/fetch_dependency_graph.rs +++ b/apollo-federation/src/query_plan/fetch_dependency_graph.rs @@ -3352,11 +3352,7 @@ pub(crate) fn compute_nodes_for_tree( initial_defer_context: DeferContext, initial_conditions: &OpGraphPathContext, ) -> Result, FederationError> { - snapshot!( - "OpPathTree", - serde_json_bytes::json!(initial_tree.to_string()).to_string(), - "path_tree" - ); + snapshot!("OpPathTree", initial_tree.to_string(), "path_tree"); let mut stack = vec![ComputeNodesStackItem { tree: initial_tree, node_id: initial_node_id, @@ -3443,7 +3439,11 @@ pub(crate) fn compute_nodes_for_tree( } } } - snapshot!(dependency_graph, "updated_dependency_graph"); + snapshot!( + "FetchDependencyGraph", + dependency_graph.to_dot(), + "Fetch dependency graph updated by compute_nodes_for_tree" + ); Ok(created_nodes) } diff --git a/apollo-federation/src/query_plan/query_planner.rs b/apollo-federation/src/query_plan/query_planner.rs index 500076ce4c..24e0972944 100644 --- a/apollo-federation/src/query_plan/query_planner.rs +++ b/apollo-federation/src/query_plan/query_planner.rs @@ -11,6 +11,7 @@ use apollo_compiler::ExecutableDocument; use apollo_compiler::Name; use itertools::Itertools; use serde::Serialize; +use tracing::trace; use super::fetch_dependency_graph::FetchIdGenerator; use super::ConditionNode; @@ -551,7 +552,15 @@ impl QueryPlanner { statistics, }; - snapshot!(plan, "query plan"); + snapshot!( + "QueryPlan", + plan.to_string(), + "QueryPlan from build_query_plan" + ); + snapshot!( + plan.statistics, + "QueryPlanningStatistics from build_query_plan" + ); Ok(plan) } @@ -716,7 +725,11 @@ pub(crate) fn compute_root_fetch_groups( root_kind, root_type.clone(), )?; - snapshot!(dependency_graph, "tree_with_root_node"); + snapshot!( + "FetchDependencyGraph", + dependency_graph.to_dot(), + "tree_with_root_node" + ); compute_nodes_for_tree( dependency_graph, &child.tree, @@ -737,16 +750,13 @@ fn compute_root_parallel_dependency_graph( parameters: &QueryPlanningParameters, has_defers: bool, ) -> Result { - snapshot!( - "FetchDependencyGraph", - "Empty", - "Starting process to construct a parallel fetch dependency graph" - ); + trace!("Starting process to construct a parallel fetch dependency graph"); let selection_set = parameters.operation.selection_set.clone(); let best_plan = compute_root_parallel_best_plan(parameters, selection_set, has_defers)?; snapshot!( - best_plan.fetch_dependency_graph, - "Plan returned from compute_root_parallel_best_plan" + "FetchDependencyGraph", + best_plan.fetch_dependency_graph.to_dot(), + "Fetch dependency graph returned from compute_root_parallel_best_plan" ); Ok(best_plan.fetch_dependency_graph) } @@ -807,7 +817,8 @@ fn compute_plan_internal( let (main, deferred) = dependency_graph.process(&mut *processor, root_kind)?; snapshot!( - dependency_graph, + "FetchDependencyGraph", + dependency_graph.to_dot(), "Plan after calling FetchDependencyGraph::process" ); // XXX(@goto-bus-stop) Maybe `.defer_tracking` should be on the return value of `process()`..? diff --git a/apollo-federation/src/query_plan/query_planning_traversal.rs b/apollo-federation/src/query_plan/query_planning_traversal.rs index 787013471a..055498218f 100644 --- a/apollo-federation/src/query_plan/query_planning_traversal.rs +++ b/apollo-federation/src/query_plan/query_planning_traversal.rs @@ -46,8 +46,17 @@ use crate::schema::position::CompositeTypeDefinitionPosition; use crate::schema::position::ObjectTypeDefinitionPosition; use crate::schema::position::SchemaRootDefinitionKind; use crate::schema::ValidFederationSchema; +use crate::utils::logging::format_open_branch; use crate::utils::logging::snapshot; +#[cfg(feature = "snapshot_tracing")] +mod snapshot_helper { + // A module to import functions only used within `snapshot!(...)` macros. + pub(crate) use crate::utils::logging::closed_branches_to_string; + pub(crate) use crate::utils::logging::open_branch_to_string; + pub(crate) use crate::utils::logging::open_branches_to_string; +} + // PORT_NOTE: Named `PlanningParameters` in the JS codebase, but there was no particular reason to // leave out to the `Query` prefix, so it's been added for consistency. Similar to `GraphPath`, we // don't have a distinguished type for when the head is a root vertex, so we instead check this at @@ -113,13 +122,33 @@ pub(crate) struct QueryPlanningTraversal<'a, 'b> { } #[derive(Debug, Serialize)] -struct OpenBranchAndSelections { +pub(crate) struct OpenBranchAndSelections { /// The options for this open branch. open_branch: OpenBranch, /// A stack of the remaining selections to plan from the node this open branch ends on. selections: Vec, } +impl std::fmt::Display for OpenBranchAndSelections { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let Some((current_selection, remaining_selections)) = self.selections.split_last() else { + return Ok(()); + }; + format_open_branch(f, &(current_selection, &self.open_branch.0))?; + write!(f, " * Remaining selections:")?; + if remaining_selections.is_empty() { + writeln!(f, " (none)")?; + } else { + // Print in reverse order since remaining selections are processed in that order. + writeln!(f)?; // newline + for selection in remaining_selections.iter().rev() { + writeln!(f, " - {selection}")?; + } + } + Ok(()) + } +} + struct PlanInfo { fetch_dependency_graph: FetchDependencyGraph, path_tree: Arc, @@ -284,7 +313,17 @@ impl<'a: 'b, 'b> QueryPlanningTraversal<'a, 'b> { ) )] fn find_best_plan_inner(&mut self) -> Result, FederationError> { - while let Some(mut current_branch) = self.open_branches.pop() { + while !self.open_branches.is_empty() { + snapshot!( + "OpenBranches", + snapshot_helper::open_branches_to_string(&self.open_branches), + "Query planning open branches" + ); + let Some(mut current_branch) = self.open_branches.pop() else { + return Err(FederationError::internal( + "Branch stack unexpectedly empty during query plan traversal", + )); + }; let Some(current_selection) = current_branch.selections.pop() else { return Err(FederationError::internal( "Sub-stack unexpectedly empty during query plan traversal", @@ -293,7 +332,7 @@ impl<'a: 'b, 'b> QueryPlanningTraversal<'a, 'b> { let (terminate_planning, new_branch) = self.handle_open_branch(¤t_selection, &mut current_branch.open_branch.0)?; if terminate_planning { - trace!("Planning termianted!"); + trace!("Planning terminated!"); // We clear both open branches and closed ones as a means to terminate the plan // computation with no plan. self.open_branches = vec![]; @@ -330,12 +369,10 @@ impl<'a: 'b, 'b> QueryPlanningTraversal<'a, 'b> { let mut new_options = vec![]; let mut no_followups: bool = false; - snapshot!(name = "Options", options, "options"); - snapshot!( - "OperationElement", - operation_element.to_string(), - "operation_element" + "OpenBranch", + snapshot_helper::open_branch_to_string(selection, options), + "open branch" ); for option in options.iter_mut() { @@ -368,7 +405,11 @@ impl<'a: 'b, 'b> QueryPlanningTraversal<'a, 'b> { } } - snapshot!(new_options, "new_options"); + snapshot!( + "OpenBranch", + snapshot_helper::open_branch_to_string(selection, &new_options), + "new_options" + ); if no_followups { // This operation element is valid from this option, but is guarantee to yield no result @@ -610,8 +651,8 @@ impl<'a: 'b, 'b> QueryPlanningTraversal<'a, 'b> { )] fn compute_best_plan_from_closed_branches(&mut self) -> Result<(), FederationError> { snapshot!( - name = "ClosedBranches", - self.closed_branches, + "ClosedBranches", + snapshot_helper::closed_branches_to_string(&self.closed_branches), "closed_branches" ); @@ -622,8 +663,8 @@ impl<'a: 'b, 'b> QueryPlanningTraversal<'a, 'b> { self.reduce_options_if_needed(); snapshot!( - name = "ClosedBranches", - self.closed_branches, + "ClosedBranches", + snapshot_helper::closed_branches_to_string(&self.closed_branches), "closed_branches_after_reduce" ); @@ -653,7 +694,7 @@ impl<'a: 'b, 'b> QueryPlanningTraversal<'a, 'b> { let (first_group, second_group) = self.closed_branches.split_at(sole_path_branch_index); let initial_tree; - snapshot!("FetchDependencyGraph", "", "Generating initial dep graph"); + trace!("Generating initial fetch dependency graph"); let mut initial_dependency_graph = self.new_dependency_graph(); let federated_query_graph = &self.parameters.federated_query_graph; let root = &self.parameters.head; @@ -678,21 +719,32 @@ impl<'a: 'b, 'b> QueryPlanningTraversal<'a, 'b> { self.parameters.config.type_conditioned_fetching, )?; snapshot!( - initial_dependency_graph, + "FetchDependencyGraph", + initial_dependency_graph.to_dot(), "Updated dep graph with initial tree" ); if first_group.is_empty() { // Well, we have the only possible plan; it's also the best. let cost = self.cost(&mut initial_dependency_graph)?; - self.best_plan = BestQueryPlanInfo { + let best_plan = BestQueryPlanInfo { fetch_dependency_graph: initial_dependency_graph, path_tree: initial_tree.into(), cost, - } - .into(); + }; - snapshot!(self.best_plan, "best_plan"); + snapshot!( + "FetchDependencyGraph", + best_plan.fetch_dependency_graph.to_dot(), + "best_plan.fetch_dependency_graph" + ); + snapshot!( + "OpPathTree", + best_plan.path_tree.to_string(), + "best_plan.path_tree" + ); + snapshot!(best_plan.cost, "best_plan.cost"); + self.best_plan = best_plan.into(); return Ok(()); } } @@ -723,14 +775,25 @@ impl<'a: 'b, 'b> QueryPlanningTraversal<'a, 'b> { other_trees, /*plan_builder*/ self, )?; - self.best_plan = BestQueryPlanInfo { + let best_plan = BestQueryPlanInfo { fetch_dependency_graph: best.fetch_dependency_graph, path_tree: best.path_tree, cost, - } - .into(); + }; + + snapshot!( + "FetchDependencyGraph", + best_plan.fetch_dependency_graph.to_dot(), + "best_plan.fetch_dependency_graph" + ); + snapshot!( + "OpPathTree", + best_plan.path_tree.to_string(), + "best_plan.path_tree" + ); + snapshot!(best_plan.cost, "best_plan.cost"); - snapshot!(self.best_plan, "best_plan"); + self.best_plan = best_plan.into(); Ok(()) } @@ -975,7 +1038,11 @@ impl<'a: 'b, 'b> QueryPlanningTraversal<'a, 'b> { )?; } - snapshot!(dependency_graph, "updated_dependency_graph"); + snapshot!( + "FetchDependencyGraph", + dependency_graph.to_dot(), + "updated_dependency_graph" + ); Ok(()) } diff --git a/apollo-federation/src/utils/logging.rs b/apollo-federation/src/utils/logging.rs index c7a07c2ef2..0b247c1698 100644 --- a/apollo-federation/src/utils/logging.rs +++ b/apollo-federation/src/utils/logging.rs @@ -1,3 +1,10 @@ +#![allow(dead_code)] + +use crate::operation::Selection; +use crate::query_graph::graph_path::ClosedBranch; +use crate::query_graph::graph_path::SimultaneousPathsWithLazyIndirectPaths; +use crate::query_plan::query_planning_traversal::OpenBranchAndSelections; + /// This macro is a wrapper around `tracing::trace!` and should not be confused with our snapshot /// testing. This primary goal of this macro is to add the necessary context to logging statements /// so that external tools (like the snapshot log visualizer) can show how various key data @@ -32,17 +39,6 @@ macro_rules! snapshot { $msg ); }; - (name = $name:literal, $value:expr, $msg:literal) => { - #[cfg(feature = "snapshot_tracing")] - tracing::trace!( - snapshot = std::any::type_name_of_val(&$value), - data = ron::ser::to_string(&$value).expect(concat!( - "Could not serialize value for a snapshot with message: ", - $msg - )), - $msg - ); - }; ($name:literal, $value:expr, $msg:literal) => { #[cfg(feature = "snapshot_tracing")] tracing::trace!(snapshot = $name, data = $value, $msg); @@ -50,3 +46,76 @@ macro_rules! snapshot { } pub(crate) use snapshot; + +pub(crate) fn make_string( + data: &T, + writer: fn(&mut std::fmt::Formatter<'_>, &T) -> std::fmt::Result, +) -> String { + // One-off struct to implement `Display` for `data` using `writer`. + struct Stringify<'a, T: ?Sized> { + data: &'a T, + writer: fn(&mut std::fmt::Formatter<'_>, &T) -> std::fmt::Result, + } + + impl<'a, T: ?Sized> std::fmt::Display for Stringify<'a, T> { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + (self.writer)(f, self.data) + } + } + + Stringify { data, writer }.to_string() +} + +// PORT_NOTE: This is a (partial) port of `QueryPlanningTraversal.debugStack` JS method. +pub(crate) fn format_open_branch( + f: &mut std::fmt::Formatter<'_>, + (selection, options): &(&Selection, &[SimultaneousPathsWithLazyIndirectPaths]), +) -> std::fmt::Result { + writeln!(f, "{selection}")?; + writeln!(f, " * Options:")?; + for option in *options { + writeln!(f, " - {option}")?; + } + Ok(()) +} + +pub(crate) fn open_branch_to_string( + selection: &Selection, + options: &[SimultaneousPathsWithLazyIndirectPaths], +) -> String { + make_string(&(selection, options), format_open_branch) +} + +// PORT_NOTE: This is a port of `QueryPlanningTraversal.debugStack` JS method. +pub(crate) fn format_open_branches( + f: &mut std::fmt::Formatter<'_>, + open_branches: &[OpenBranchAndSelections], +) -> std::fmt::Result { + // Print from the stack top to the bottom. + for branch in open_branches.iter().rev() { + writeln!(f, "{branch}")?; + } + Ok(()) +} + +pub(crate) fn open_branches_to_string(open_branches: &[OpenBranchAndSelections]) -> String { + make_string(open_branches, format_open_branches) +} + +pub(crate) fn format_closed_branches( + f: &mut std::fmt::Formatter<'_>, + closed_branches: &[ClosedBranch], +) -> std::fmt::Result { + writeln!(f, "All branches:")?; + for (i, closed_branch) in closed_branches.iter().enumerate() { + writeln!(f, "{i}:")?; + for closed_path in &closed_branch.0 { + writeln!(f, " - {closed_path}")?; + } + } + Ok(()) +} + +pub(crate) fn closed_branches_to_string(closed_branches: &[ClosedBranch]) -> String { + make_string(closed_branches, format_closed_branches) +} From 336c42d401611117da503b1c96c5a541648c11eb Mon Sep 17 00:00:00 2001 From: Geoffroy Couprie Date: Tue, 29 Oct 2024 11:48:07 +0100 Subject: [PATCH 11/77] defer integration tests (#6007) --- apollo-router/tests/common.rs | 1 - .../{basic/query1 => core/defer}/README.md | 0 .../query1 => core/defer}/configuration.yaml | 0 .../tests/samples/core/defer/plan.json | 106 +++++++++++++++ .../query2 => core/defer}/supergraph.graphql | 0 .../{basic/query2 => core/query1}/README.md | 0 .../query2 => core/query1}/configuration.yaml | 0 .../samples/{basic => core}/query1/plan.json | 0 .../{basic => core}/query1/supergraph.graphql | 0 .../tests/samples/core/query2/README.md | 3 + .../samples/core/query2/configuration.yaml | 4 + .../samples/{basic => core}/query2/plan.json | 0 .../samples/core/query2/supergraph.graphql | 125 ++++++++++++++++++ .../enterprise/entity-cache/defer/README.md | 3 + .../entity-cache/defer/configuration.yaml | 23 ++++ .../enterprise/entity-cache/defer/plan.json | 113 ++++++++++++++++ .../entity-cache/defer/supergraph.graphql | 122 +++++++++++++++++ apollo-router/tests/samples_tests.rs | 115 ++++++++++++++-- 18 files changed, 605 insertions(+), 10 deletions(-) rename apollo-router/tests/samples/{basic/query1 => core/defer}/README.md (100%) rename apollo-router/tests/samples/{basic/query1 => core/defer}/configuration.yaml (100%) create mode 100644 apollo-router/tests/samples/core/defer/plan.json rename apollo-router/tests/samples/{basic/query2 => core/defer}/supergraph.graphql (100%) rename apollo-router/tests/samples/{basic/query2 => core/query1}/README.md (100%) rename apollo-router/tests/samples/{basic/query2 => core/query1}/configuration.yaml (100%) rename apollo-router/tests/samples/{basic => core}/query1/plan.json (100%) rename apollo-router/tests/samples/{basic => core}/query1/supergraph.graphql (100%) create mode 100644 apollo-router/tests/samples/core/query2/README.md create mode 100644 apollo-router/tests/samples/core/query2/configuration.yaml rename apollo-router/tests/samples/{basic => core}/query2/plan.json (100%) create mode 100644 apollo-router/tests/samples/core/query2/supergraph.graphql create mode 100644 apollo-router/tests/samples/enterprise/entity-cache/defer/README.md create mode 100644 apollo-router/tests/samples/enterprise/entity-cache/defer/configuration.yaml create mode 100644 apollo-router/tests/samples/enterprise/entity-cache/defer/plan.json create mode 100644 apollo-router/tests/samples/enterprise/entity-cache/defer/supergraph.graphql diff --git a/apollo-router/tests/common.rs b/apollo-router/tests/common.rs index 826a377e04..671c462519 100644 --- a/apollo-router/tests/common.rs +++ b/apollo-router/tests/common.rs @@ -587,7 +587,6 @@ impl IntegrationTest { let mut request = builder.json(&query).build().unwrap(); telemetry.inject_context(&mut request); - request.headers_mut().remove(ACCEPT); match client.execute(request).await { Ok(response) => (span_id, response), Err(err) => { diff --git a/apollo-router/tests/samples/basic/query1/README.md b/apollo-router/tests/samples/core/defer/README.md similarity index 100% rename from apollo-router/tests/samples/basic/query1/README.md rename to apollo-router/tests/samples/core/defer/README.md diff --git a/apollo-router/tests/samples/basic/query1/configuration.yaml b/apollo-router/tests/samples/core/defer/configuration.yaml similarity index 100% rename from apollo-router/tests/samples/basic/query1/configuration.yaml rename to apollo-router/tests/samples/core/defer/configuration.yaml diff --git a/apollo-router/tests/samples/core/defer/plan.json b/apollo-router/tests/samples/core/defer/plan.json new file mode 100644 index 0000000000..b2499400bd --- /dev/null +++ b/apollo-router/tests/samples/core/defer/plan.json @@ -0,0 +1,106 @@ +{ + "actions": [ + { + "type": "Start", + "schema_path": "./supergraph.graphql", + "configuration_path": "./configuration.yaml", + "subgraphs": { + "accounts": { + "requests": [ + { + "request": { + "body": { + "query": "{me{__typename name id}}" + } + }, + "response": { + "body": { + "data": { + "me": { + "__typename": "User", + "name": "test", + "id": "1" + } + } + } + } + } + ] + }, + "reviews": { + "requests": [ + { + "request": { + "body": { + "query": "query($representations:[_Any!]!){_entities(representations:$representations){...on User{reviews{body}}}}", + "variables": { + "representations": [ + { + "__typename": "User", + "id": "1" + } + ] + } + } + }, + "response": { + "body": { + "data": { + "_entities": [ + { + "reviews": [ + { + "body": "Test" + } + ] + } + ] + } + } + } + } + ] + } + } + }, + { + "type": "Request", + "headers": { + "Accept": "multipart/mixed;deferSpec=20220824" + }, + "request": { + "query": "{ me { name ... @defer { reviews { body } } } }" + }, + "expected_response": [ + { + "data": { + "me": { + "name": "test" + } + }, + "hasNext": true + }, + { + "hasNext": false, + "incremental": [ + { + "data": { + "reviews": [ + { + "body": "Test" + } + ] + }, + "path": [ + "me" + ] + } + ] + } + ] + }, + { + "type": "Stop" + } + ] +} \ No newline at end of file diff --git a/apollo-router/tests/samples/basic/query2/supergraph.graphql b/apollo-router/tests/samples/core/defer/supergraph.graphql similarity index 100% rename from apollo-router/tests/samples/basic/query2/supergraph.graphql rename to apollo-router/tests/samples/core/defer/supergraph.graphql diff --git a/apollo-router/tests/samples/basic/query2/README.md b/apollo-router/tests/samples/core/query1/README.md similarity index 100% rename from apollo-router/tests/samples/basic/query2/README.md rename to apollo-router/tests/samples/core/query1/README.md diff --git a/apollo-router/tests/samples/basic/query2/configuration.yaml b/apollo-router/tests/samples/core/query1/configuration.yaml similarity index 100% rename from apollo-router/tests/samples/basic/query2/configuration.yaml rename to apollo-router/tests/samples/core/query1/configuration.yaml diff --git a/apollo-router/tests/samples/basic/query1/plan.json b/apollo-router/tests/samples/core/query1/plan.json similarity index 100% rename from apollo-router/tests/samples/basic/query1/plan.json rename to apollo-router/tests/samples/core/query1/plan.json diff --git a/apollo-router/tests/samples/basic/query1/supergraph.graphql b/apollo-router/tests/samples/core/query1/supergraph.graphql similarity index 100% rename from apollo-router/tests/samples/basic/query1/supergraph.graphql rename to apollo-router/tests/samples/core/query1/supergraph.graphql diff --git a/apollo-router/tests/samples/core/query2/README.md b/apollo-router/tests/samples/core/query2/README.md new file mode 100644 index 0000000000..9386489fb0 --- /dev/null +++ b/apollo-router/tests/samples/core/query2/README.md @@ -0,0 +1,3 @@ +This is an example test + +This file adds some context that will be displayed on test failure \ No newline at end of file diff --git a/apollo-router/tests/samples/core/query2/configuration.yaml b/apollo-router/tests/samples/core/query2/configuration.yaml new file mode 100644 index 0000000000..f7ed04641e --- /dev/null +++ b/apollo-router/tests/samples/core/query2/configuration.yaml @@ -0,0 +1,4 @@ +override_subgraph_url: + products: http://localhost:4005 +include_subgraph_errors: + all: true diff --git a/apollo-router/tests/samples/basic/query2/plan.json b/apollo-router/tests/samples/core/query2/plan.json similarity index 100% rename from apollo-router/tests/samples/basic/query2/plan.json rename to apollo-router/tests/samples/core/query2/plan.json diff --git a/apollo-router/tests/samples/core/query2/supergraph.graphql b/apollo-router/tests/samples/core/query2/supergraph.graphql new file mode 100644 index 0000000000..1bd9f596ee --- /dev/null +++ b/apollo-router/tests/samples/core/query2/supergraph.graphql @@ -0,0 +1,125 @@ +schema + @link(url: "https://specs.apollo.dev/link/v1.0") + @link(url: "https://specs.apollo.dev/inaccessible/v0.2", for: SECURITY) + @link(url: "https://specs.apollo.dev/join/v0.3", for: EXECUTION) { + query: Query + mutation: Mutation +} + +directive @inaccessible on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION + +directive @tag( + name: String! +) repeatable on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION | SCHEMA + +directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE + +directive @join__field( + graph: join__Graph + requires: join__FieldSet + provides: join__FieldSet + type: String + external: Boolean + override: String + usedOverridden: Boolean +) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + +directive @join__graph(name: String!, url: String!) on ENUM_VALUE + +directive @join__implements( + graph: join__Graph! + interface: String! +) repeatable on OBJECT | INTERFACE + +directive @join__type( + graph: join__Graph! + key: join__FieldSet + extension: Boolean! = false + resolvable: Boolean! = true + isInterfaceObject: Boolean! = false +) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + +directive @join__unionMember( + graph: join__Graph! + member: String! +) repeatable on UNION + +directive @link( + url: String + as: String + for: link__Purpose + import: [link__Import] +) repeatable on SCHEMA + +scalar join__FieldSet + +enum join__Graph { + ACCOUNTS + @join__graph(name: "accounts", url: "https://accounts.demo.starstuff.dev/") + INVENTORY + @join__graph( + name: "inventory" + url: "https://inventory.demo.starstuff.dev/" + ) + PRODUCTS + @join__graph(name: "products", url: "https://products.demo.starstuff.dev/") + REVIEWS + @join__graph(name: "reviews", url: "https://reviews.demo.starstuff.dev/") +} + +scalar link__Import + +enum link__Purpose { + SECURITY + EXECUTION +} + +type Mutation @join__type(graph: PRODUCTS) @join__type(graph: REVIEWS) { + createProduct(upc: ID!, name: String): Product @join__field(graph: PRODUCTS) + createReview(upc: ID!, id: ID!, body: String): Review + @join__field(graph: REVIEWS) +} + +type Product + @join__type(graph: INVENTORY, key: "upc") + @join__type(graph: PRODUCTS, key: "upc") + @join__type(graph: REVIEWS, key: "upc") { + inStock: Boolean + @join__field(graph: INVENTORY) + @tag(name: "private") + @inaccessible + name: String @join__field(graph: PRODUCTS) + weight: Int @join__field(graph: INVENTORY, external: true) @join__field(graph: PRODUCTS) + price: Int @join__field(graph: INVENTORY, external: true) @join__field(graph: PRODUCTS) + reviews: [Review] @join__field(graph: REVIEWS) + reviewsForAuthor(authorID: ID!): [Review] @join__field(graph: REVIEWS) + shippingEstimate: Int @join__field(graph: INVENTORY, requires: "price weight") + upc: String! +} + +type Query + @join__type(graph: ACCOUNTS) + @join__type(graph: INVENTORY) + @join__type(graph: PRODUCTS) + @join__type(graph: REVIEWS) { + me: User @join__field(graph: ACCOUNTS) + topProducts(first: Int = 5): [Product] @join__field(graph: PRODUCTS) +} + +type Review @join__type(graph: REVIEWS, key: "id") { + id: ID! + body: String @join__field(graph: REVIEWS) + author: User @join__field(graph: REVIEWS, provides: "username") + product: Product @join__field(graph: REVIEWS) +} + +type User + @join__type(graph: ACCOUNTS, key: "id") + @join__type(graph: REVIEWS, key: "id") { + id: ID! + name: String @join__field(graph: ACCOUNTS) + username: String + @join__field(graph: ACCOUNTS) + @join__field(graph: REVIEWS, external: true) + reviews: [Review] @join__field(graph: REVIEWS) +} diff --git a/apollo-router/tests/samples/enterprise/entity-cache/defer/README.md b/apollo-router/tests/samples/enterprise/entity-cache/defer/README.md new file mode 100644 index 0000000000..a96d350b73 --- /dev/null +++ b/apollo-router/tests/samples/enterprise/entity-cache/defer/README.md @@ -0,0 +1,3 @@ +# Entity cache with @defer + +This tests `Cache-Control` aggregation when using the `@defer` directive. \ No newline at end of file diff --git a/apollo-router/tests/samples/enterprise/entity-cache/defer/configuration.yaml b/apollo-router/tests/samples/enterprise/entity-cache/defer/configuration.yaml new file mode 100644 index 0000000000..fb6b95ecd4 --- /dev/null +++ b/apollo-router/tests/samples/enterprise/entity-cache/defer/configuration.yaml @@ -0,0 +1,23 @@ +override_subgraph_url: + products: http://localhost:4005 +include_subgraph_errors: + all: true + +preview_entity_cache: + enabled: true + redis: + urls: + ["redis://localhost:6379",] + subgraph: + all: + enabled: true + subgraphs: + reviews: + ttl: 120s + enabled: true + +telemetry: + exporters: + logging: + stdout: + format: text \ No newline at end of file diff --git a/apollo-router/tests/samples/enterprise/entity-cache/defer/plan.json b/apollo-router/tests/samples/enterprise/entity-cache/defer/plan.json new file mode 100644 index 0000000000..265e282056 --- /dev/null +++ b/apollo-router/tests/samples/enterprise/entity-cache/defer/plan.json @@ -0,0 +1,113 @@ +{ + "enterprise": true, + "redis": true, + "actions": [ + { + "type": "Start", + "schema_path": "./supergraph.graphql", + "configuration_path": "./configuration.yaml", + "subgraphs": { + "cache-defer-accounts": { + "requests": [ + { + "request": { + "body": { + "query": "query CacheDefer__cache_defer_accounts__0{me{__typename name id}}", + "operationName": "CacheDefer__cache_defer_accounts__0" + } + }, + "response": { + "headers": { + "Cache-Control": "public, max-age=10", + "Content-Type": "application/json" + }, + "body": { + "data": { + "me": { + "__typename": "User", + "name": "test-user", + "id": "1" + } + } + } + } + } + ] + }, + "cache-defer-reviews": { + "requests": [ + { + "request": { + "body": { + "query": "query CacheDefer__cache_defer_reviews__1($representations:[_Any!]!){_entities(representations:$representations){...on User{reviews{body}}}}", + "operationName": "CacheDefer__cache_defer_reviews__1", + "variables": { + "representations": [ + { + "id": "1", + "__typename": "User" + } + ] + } + } + }, + "response": { + "headers": { + "Cache-Control": "public, max-age=100", + "Content-Type": "application/json" + }, + "body": { + "data": { + "reviews": [ + { + "body": "test-review" + } + ] + } + } + } + } + ] + } + } + }, + { + "type": "Request", + "request": { + "query": "query CacheDefer { me { name ... @defer { reviews { body } } } }" + }, + "headers": { + "Accept": "multipart/mixed;deferSpec=20220824" + }, + "expected_response": [ + { + "data": { + "me": { + "name": "test-user" + } + }, + "hasNext": true + }, + { + "hasNext": false, + "incremental": [ + { + "data": { + "reviews": null + }, + "path": [ + "me" + ] + } + ] + } + ], + "expected_headers": { + "Cache-Control": "max-age=10,public" + } + }, + { + "type": "Stop" + } + ] +} \ No newline at end of file diff --git a/apollo-router/tests/samples/enterprise/entity-cache/defer/supergraph.graphql b/apollo-router/tests/samples/enterprise/entity-cache/defer/supergraph.graphql new file mode 100644 index 0000000000..320a9c2a70 --- /dev/null +++ b/apollo-router/tests/samples/enterprise/entity-cache/defer/supergraph.graphql @@ -0,0 +1,122 @@ +schema + @link(url: "https://specs.apollo.dev/link/v1.0") + @link(url: "https://specs.apollo.dev/tag/v0.3") + @link(url: "https://specs.apollo.dev/inaccessible/v0.2") + @link(url: "https://specs.apollo.dev/join/v0.3", for: EXECUTION) { + query: Query + mutation: Mutation +} + +directive @inaccessible on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION +directive @tag( + name: String! +) repeatable on FIELD_DEFINITION | INTERFACE | OBJECT | UNION + +directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE + +directive @join__field( + graph: join__Graph + requires: join__FieldSet + provides: join__FieldSet + type: String + external: Boolean + override: String + usedOverridden: Boolean +) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + +directive @join__graph(name: String!, url: String!) on ENUM_VALUE + +directive @join__implements( + graph: join__Graph! + interface: String! +) repeatable on OBJECT | INTERFACE + +directive @join__type( + graph: join__Graph! + key: join__FieldSet + extension: Boolean! = false + resolvable: Boolean! = true + isInterfaceObject: Boolean! = false +) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + +directive @join__unionMember( + graph: join__Graph! + member: String! +) repeatable on UNION + +directive @link( + url: String + as: String + for: link__Purpose + import: [link__Import] +) repeatable on SCHEMA + +scalar join__FieldSet +scalar link__Import + +enum join__Graph { + ACCOUNTS @join__graph(name: "cache-defer-accounts", url: "https://accounts.demo.starstuff.dev") + INVENTORY @join__graph(name: "inventory", url: "https://inventory.demo.starstuff.dev") + PRODUCTS @join__graph(name: "products", url: "https://products.demo.starstuff.dev") + REVIEWS @join__graph(name: "cache-defer-reviews", url: "https://reviews.demo.starstuff.dev") +} + +enum link__Purpose { + SECURITY + EXECUTION +} + +type Mutation + @join__type(graph: PRODUCTS) + @join__type(graph: REVIEWS) + @join__type(graph: ACCOUNTS) { + updateMyAccount: User @join__field(graph: ACCOUNTS) + createProduct(name: String, upc: ID!): Product @join__field(graph: PRODUCTS) + createReview(body: String, id: ID!, upc: ID!): Review + @join__field(graph: REVIEWS) +} + +type Product + @join__type(graph: ACCOUNTS, key: "upc", extension: true) + @join__type(graph: INVENTORY, key: "upc") + @join__type(graph: PRODUCTS, key: "upc") + @join__type(graph: REVIEWS, key: "upc") { + inStock: Boolean + @join__field(graph: INVENTORY) + @tag(name: "private") + @inaccessible + name: String @join__field(graph: PRODUCTS) + weight: Int @join__field(graph: INVENTORY, external: true) @join__field(graph: PRODUCTS) + price: Int @join__field(graph: INVENTORY, external: true) @join__field(graph: PRODUCTS) + reviews: [Review] @join__field(graph: REVIEWS) + reviewsForAuthor(authorID: ID!): [Review] @join__field(graph: REVIEWS) + shippingEstimate: Int @join__field(graph: INVENTORY, requires: "price weight") + upc: String! +} + +type Query + @join__type(graph: ACCOUNTS) + @join__type(graph: INVENTORY) + @join__type(graph: PRODUCTS) + @join__type(graph: REVIEWS) { + me: User @join__field(graph: ACCOUNTS) + topProducts(first: Int = 5): [Product] @join__field(graph: PRODUCTS) +} + +type Review @join__type(graph: REVIEWS, key: "id") { + id: ID! + author: User @join__field(graph: REVIEWS, provides: "username") + body: String + product: Product +} + +type User + @join__type(graph: ACCOUNTS, key: "id") + @join__type(graph: REVIEWS, key: "id") { + id: ID! + name: String @join__field(graph: ACCOUNTS) + username: String + @join__field(graph: ACCOUNTS) + @join__field(graph: REVIEWS, external: true) + reviews: [Review] @join__field(graph: REVIEWS) +} diff --git a/apollo-router/tests/samples_tests.rs b/apollo-router/tests/samples_tests.rs index 22e3b31e18..4686bd644c 100644 --- a/apollo-router/tests/samples_tests.rs +++ b/apollo-router/tests/samples_tests.rs @@ -14,6 +14,9 @@ use std::process::ExitCode; use libtest_mimic::Arguments; use libtest_mimic::Failed; use libtest_mimic::Trial; +use mediatype::MediaTypeList; +use mediatype::ReadParams; +use multer::Multipart; use serde::Deserialize; use serde_json::Value; use tokio::runtime::Runtime; @@ -173,12 +176,14 @@ impl TestExecution { query_path, headers, expected_response, + expected_headers, } => { self.request( request.clone(), query_path.as_deref(), headers, expected_response, + expected_headers, path, out, ) @@ -405,12 +410,14 @@ impl TestExecution { } } + #[allow(clippy::too_many_arguments)] async fn request( &mut self, mut request: Value, query_path: Option<&str>, headers: &HashMap, expected_response: &Value, + expected_headers: &HashMap, path: &Path, out: &mut String, ) -> Result<(), Failed> { @@ -434,19 +441,107 @@ impl TestExecution { } writeln!(out, "query: {}\n", serde_json::to_string(&request).unwrap()).unwrap(); + writeln!(out, "header: {:?}\n", headers).unwrap(); + let (_, response) = router .execute_query_with_headers(&request, headers.clone()) .await; - let body = response.bytes().await.map_err(|e| { - writeln!(out, "could not get graphql response data: {e}").unwrap(); - let f: Failed = out.clone().into(); - f - })?; - let graphql_response: Value = serde_json::from_slice(&body).map_err(|e| { - writeln!(out, "could not deserialize graphql response data: {e}").unwrap(); + writeln!(out, "response headers: {:?}", response.headers()).unwrap(); + + let mut failed = false; + for (key, value) in expected_headers { + if !response.headers().contains_key(key) { + failed = true; + writeln!(out, "expected header {} to be present", key).unwrap(); + } else if response.headers().get(key).unwrap() != value { + failed = true; + writeln!( + out, + "expected header {} to be {}, got {:?}", + key, + value, + response.headers().get(key).unwrap() + ) + .unwrap(); + } + } + if failed { let f: Failed = out.clone().into(); - f - })?; + return Err(f); + } + + let content_type = response + .headers() + .get("content-type") + .unwrap() + .to_str() + .unwrap(); + let mut is_multipart = false; + let mut boundary = None; + for mime in MediaTypeList::new(content_type).flatten() { + if mime.ty == mediatype::names::MULTIPART && mime.subty == mediatype::names::MIXED { + is_multipart = true; + boundary = mime.get_param(mediatype::names::BOUNDARY).map(|v| { + // multer does not strip quotes from the boundary: https://github.com/rwf2/multer/issues/64 + let mut s = v.as_str(); + if s.starts_with('\"') && s.ends_with('\"') { + s = &s[1..s.len() - 1]; + } + + s.to_string() + }); + } + } + + let graphql_response: Value = if !is_multipart { + let body = response.bytes().await.map_err(|e| { + writeln!(out, "could not get graphql response data: {e}").unwrap(); + let f: Failed = out.clone().into(); + f + })?; + serde_json::from_slice(&body).map_err(|e| { + writeln!( + out, + "could not deserialize graphql response data: {e}\nfrom:\n{}", + std::str::from_utf8(&body).unwrap() + ) + .unwrap(); + let f: Failed = out.clone().into(); + f + })? + } else { + let mut chunks = Vec::new(); + + let mut multipart = Multipart::new(response.bytes_stream(), boundary.unwrap()); + + // Iterate over the fields, use `next_field()` to get the next field. + while let Some(mut field) = multipart.next_field().await.map_err(|e| { + writeln!(out, "could not get next field from multipart body: {e}",).unwrap(); + let f: Failed = out.clone().into(); + f + })? { + while let Some(chunk) = field.chunk().await.map_err(|e| { + writeln!(out, "could not get next chunk from multipart body: {e}",).unwrap(); + let f: Failed = out.clone().into(); + f + })? { + writeln!(out, "multipart chunk: {:?}\n", std::str::from_utf8(&chunk)).unwrap(); + + let parsed: Value = serde_json::from_slice(&chunk).map_err(|e| { + writeln!( + out, + "could not deserialize graphql response data: {e}\nfrom:\n{}", + std::str::from_utf8(&chunk).unwrap() + ) + .unwrap(); + let f: Failed = out.clone().into(); + f + })?; + chunks.push(parsed); + } + } + Value::Array(chunks) + }; if expected_response != &graphql_response { if let Some(requests) = self @@ -583,6 +678,8 @@ enum Action { #[serde(default)] headers: HashMap, expected_response: Value, + #[serde(default)] + expected_headers: HashMap, }, EndpointRequest { url: url::Url, From 508ed0f10f2386abc51d000ccf70361a7ad2a8a0 Mon Sep 17 00:00:00 2001 From: Geoffroy Couprie Date: Tue, 29 Oct 2024 11:48:40 +0100 Subject: [PATCH 12/77] test interfaceObject (#6072) --- .../samples/basic/interface-object/README.md | 4 + .../basic/interface-object/configuration.yaml | 7 + .../samples/basic/interface-object/plan.json | 254 ++++++++++++++++++ .../basic/interface-object/supergraph.graphql | 115 ++++++++ 4 files changed, 380 insertions(+) create mode 100644 apollo-router/tests/samples/basic/interface-object/README.md create mode 100644 apollo-router/tests/samples/basic/interface-object/configuration.yaml create mode 100644 apollo-router/tests/samples/basic/interface-object/plan.json create mode 100644 apollo-router/tests/samples/basic/interface-object/supergraph.graphql diff --git a/apollo-router/tests/samples/basic/interface-object/README.md b/apollo-router/tests/samples/basic/interface-object/README.md new file mode 100644 index 0000000000..a2e1d7fbb1 --- /dev/null +++ b/apollo-router/tests/samples/basic/interface-object/README.md @@ -0,0 +1,4 @@ + +# @interfaceObject + +Test the [`@interfaceObject`](https://www.apollographql.com/docs/federation/entities/interfaces/) directive. \ No newline at end of file diff --git a/apollo-router/tests/samples/basic/interface-object/configuration.yaml b/apollo-router/tests/samples/basic/interface-object/configuration.yaml new file mode 100644 index 0000000000..d5c60afffa --- /dev/null +++ b/apollo-router/tests/samples/basic/interface-object/configuration.yaml @@ -0,0 +1,7 @@ +override_subgraph_url: + products: http://localhost:4005 +include_subgraph_errors: + all: true + +plugins: + experimental.expose_query_plan: true \ No newline at end of file diff --git a/apollo-router/tests/samples/basic/interface-object/plan.json b/apollo-router/tests/samples/basic/interface-object/plan.json new file mode 100644 index 0000000000..91a5690a0c --- /dev/null +++ b/apollo-router/tests/samples/basic/interface-object/plan.json @@ -0,0 +1,254 @@ +{ + "actions": [ + { + "type": "Start", + "schema_path": "./supergraph.graphql", + "configuration_path": "./configuration.yaml", + "subgraphs": { + "accounts": { + "requests": [ + { + "request": { + "body": { + "query": "query TestItf__accounts__0{i{__typename id x ...on A{a}...on B{b}}}", + "operationName": "TestItf__accounts__0" + } + }, + "response": { + "body": { + "data": { + "i": [ + { + "__typename": "A", + "id": "1", + "x": 1, + "a": "a" + }, + null, + { + "__typename": "B", + "id": "2", + "x": 2, + "b": "b" + }, + { + "__typename": "A", + "id": "1", + "x": 1, + "a": "a" + }, + { + "__typename": "B", + "id": "3", + "x": 3, + "b": "c" + } + ] + } + } + } + } + ] + }, + "products": { + "requests": [ + { + "request": { + "body": { + "query": "query TestItf__products__1($representations:[_Any!]!){_entities(representations:$representations){...on I{y}}}", + "operationName": "TestItf__products__1", + "variables": { + "representations": [ + { + "__typename": "I", + "id": "1" + }, + { + "__typename": "I", + "id": "2" + }, + { + "__typename": "I", + "id": "3" + } + ] + } + } + }, + "response": { + "body": { + "data": { + "_entities": [ + { + "y": 1 + }, + { + "y": 2 + }, + null + ] + } + } + } + } + ] + }, + "reviews": { + "requests": [] + } + } + }, + { + "type": "Request", + "request": { + "query": "query TestItf { i { __typename x y ... on A { a } ... on B { b } } }" + }, + "expected_response": { + "data": { + "i": [ + { + "__typename": "A", + "x": 1, + "y": 1, + "a": "a" + }, + null, + { + "__typename": "B", + "x": 2, + "y": 2, + "b": "b" + }, + { + "__typename": "A", + "x": 1, + "y": 1, + "a": "a" + }, + { + "__typename": "B", + "x": 3, + "y": null, + "b": "c" + } + ] + } + } + }, + { + "type": "ReloadSubgraphs", + "subgraphs": { + "accounts": { + "requests": [ + { + "request": { + "body": { + "query": "query TestItf2__accounts__0{req{__typename id i{__typename id x}}}", + "operationName": "TestItf2__accounts__0" + } + }, + "response": { + "body": { + "data": { + "req": { + "__typename": "C", + "id": "1", + "i": { + "__typename": "A", + "id": "1", + "x": 1 + } + } + } + } + } + } + ] + }, + "products": { + "requests": [ + { + "request": { + "body": { + "query": "query TestItf2__products__1($representations:[_Any!]!){_entities(representations:$representations){...on I{y}}}", + "operationName": "TestItf2__products__1", + "variables": { + "representations": [ + { + "__typename": "I", + "id": "1" + } + ] + } + } + }, + "response": { + "body": { + "data": { + "_entities": [ + { + "y": 1 + } + ] + } + } + } + } + ] + }, + "reviews": { + "requests": [ + { + "request": { + "body": { + "query": "query TestItf2__reviews__2($representations:[_Any!]!){_entities(representations:$representations){...on C{c}}}", + "operationName": "TestItf2__reviews__2", + "variables": { + "representations": [ + { + "__typename": "C", + "i": { + "x": 1, + "y": 1 + }, + "id": "1" + } + ] + } + } + }, + "response": { + "body": { + "data": { + "_entities": [ + { + "c": "c" + } + ] + } + } + } + } + ] + } + } + }, + { + "type": "Request", + "request": { + "query": "query TestItf2 { req { id c } }" + }, + "expected_response": { + "data": { + "req": { + "id": "1", + "c": "c" + } + } + } + }, + { + "type": "Stop" + } + ] +} \ No newline at end of file diff --git a/apollo-router/tests/samples/basic/interface-object/supergraph.graphql b/apollo-router/tests/samples/basic/interface-object/supergraph.graphql new file mode 100644 index 0000000000..08783bf70f --- /dev/null +++ b/apollo-router/tests/samples/basic/interface-object/supergraph.graphql @@ -0,0 +1,115 @@ +schema + @link(url: "https://specs.apollo.dev/link/v1.0") + @link(url: "https://specs.apollo.dev/inaccessible/v0.2", for: SECURITY) + @link(url: "https://specs.apollo.dev/join/v0.3", for: EXECUTION) { + query: Query +} + +directive @inaccessible on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION + +directive @tag( + name: String! +) repeatable on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION | SCHEMA + +directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE + +directive @join__field( + graph: join__Graph + requires: join__FieldSet + provides: join__FieldSet + type: String + external: Boolean + override: String + usedOverridden: Boolean +) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + +directive @join__graph(name: String!, url: String!) on ENUM_VALUE + +directive @join__implements( + graph: join__Graph! + interface: String! +) repeatable on OBJECT | INTERFACE + +directive @join__type( + graph: join__Graph! + key: join__FieldSet + extension: Boolean! = false + resolvable: Boolean! = true + isInterfaceObject: Boolean! = false +) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + +directive @join__unionMember( + graph: join__Graph! + member: String! +) repeatable on UNION + +directive @link( + url: String + as: String + for: link__Purpose + import: [link__Import] +) repeatable on SCHEMA + +scalar join__FieldSet +scalar link__Import + +enum join__Graph { + ACCOUNTS + @join__graph(name: "accounts", url: "https://accounts.demo.starstuff.dev/") + INVENTORY + @join__graph( + name: "inventory" + url: "https://inventory.demo.starstuff.dev/" + ) + PRODUCTS + @join__graph(name: "products", url: "https://products.demo.starstuff.dev/") + REVIEWS + @join__graph(name: "reviews", url: "https://reviews.demo.starstuff.dev/") +} + +enum link__Purpose { + SECURITY + EXECUTION +} + +type Query + @join__type(graph: ACCOUNTS) + @join__type(graph: REVIEWS) { + i: [I] @join__field(graph: ACCOUNTS) + req: C @join__field(graph: ACCOUNTS) +} + +interface I + @join__type(graph: ACCOUNTS, key: "id") + @join__type(graph: PRODUCTS, key: "id", isInterfaceObject: true) + @join__type(graph: REVIEWS) { + id: ID! + x: Int @join__field(graph: ACCOUNTS) @join__field(graph: REVIEWS) + y: Int @join__field(graph: PRODUCTS) @join__field(graph: REVIEWS) +} + +type A implements I + @join__type(graph: ACCOUNTS, key: "id") + @join__implements(graph: ACCOUNTS, interface: "I") { + id: ID! + x: Int + y: Int @join__field + a: String +} + +type B implements I + @join__type(graph: ACCOUNTS, key: "id") + @join__implements(graph: ACCOUNTS, interface: "I") { + id: ID! + x: Int + y: Int @join__field + b: String +} + +type C + @join__type(graph: ACCOUNTS, key: "id") + @join__type(graph: REVIEWS, key: "id") { + id: ID! + i: I @join__field(graph: ACCOUNTS) @join__field(graph: REVIEWS, external: true) + c: String @join__field(graph: REVIEWS, requires: "i { x y }") +} \ No newline at end of file From 83f57725483f0b195e43f47add0e0cc8f73246ca Mon Sep 17 00:00:00 2001 From: Geoffroy Couprie Date: Tue, 29 Oct 2024 11:49:01 +0100 Subject: [PATCH 13/77] update entity cache samples config (#6044) --- .../entity-cache/invalidation-entity-key/configuration.yaml | 6 +++--- .../invalidation-subgraph-name/configuration.yaml | 6 +++--- .../invalidation-subgraph-type/configuration.yaml | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/apollo-router/tests/samples/enterprise/entity-cache/invalidation-entity-key/configuration.yaml b/apollo-router/tests/samples/enterprise/entity-cache/invalidation-entity-key/configuration.yaml index e283bbdace..47f1e99e06 100644 --- a/apollo-router/tests/samples/enterprise/entity-cache/invalidation-entity-key/configuration.yaml +++ b/apollo-router/tests/samples/enterprise/entity-cache/invalidation-entity-key/configuration.yaml @@ -5,12 +5,12 @@ include_subgraph_errors: preview_entity_cache: enabled: true - redis: - urls: - ["redis://localhost:6379",] subgraph: all: enabled: true + redis: + urls: + ["redis://localhost:6379",] subgraphs: invalidation-entity-key-reviews: ttl: 120s diff --git a/apollo-router/tests/samples/enterprise/entity-cache/invalidation-subgraph-name/configuration.yaml b/apollo-router/tests/samples/enterprise/entity-cache/invalidation-subgraph-name/configuration.yaml index 85e106df9f..7efcac9a81 100644 --- a/apollo-router/tests/samples/enterprise/entity-cache/invalidation-subgraph-name/configuration.yaml +++ b/apollo-router/tests/samples/enterprise/entity-cache/invalidation-subgraph-name/configuration.yaml @@ -8,12 +8,12 @@ preview_entity_cache: invalidation: listen: 127.0.0.1:4000 path: /invalidation - redis: - urls: - ["redis://localhost:6379",] subgraph: all: enabled: true + redis: + urls: + ["redis://localhost:6379",] subgraphs: reviews: ttl: 120s diff --git a/apollo-router/tests/samples/enterprise/entity-cache/invalidation-subgraph-type/configuration.yaml b/apollo-router/tests/samples/enterprise/entity-cache/invalidation-subgraph-type/configuration.yaml index 96577bbb28..8378e3b127 100644 --- a/apollo-router/tests/samples/enterprise/entity-cache/invalidation-subgraph-type/configuration.yaml +++ b/apollo-router/tests/samples/enterprise/entity-cache/invalidation-subgraph-type/configuration.yaml @@ -5,9 +5,6 @@ include_subgraph_errors: preview_entity_cache: enabled: true - redis: - urls: - ["redis://localhost:6379",] invalidation: # FIXME: right now we cannot configure it to use the same port used for the GraphQL endpoint if it is chosen at random listen: 127.0.0.1:12345 @@ -15,6 +12,9 @@ preview_entity_cache: subgraph: all: enabled: true + redis: + urls: + ["redis://localhost:6379",] invalidation: enabled: true shared_key: "1234" From 39c6c03ed9f15c3872bcad083e1560ddbb1b6d3e Mon Sep 17 00:00:00 2001 From: Geoffroy Couprie Date: Tue, 29 Oct 2024 11:59:47 +0100 Subject: [PATCH 14/77] add errors for response validation (#5787) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Andrew McGivery Co-authored-by: Renรฉe Kooi --- .../fix_geal_response_validation_errors.md | 5 + apollo-router/src/json_ext.rs | 14 + apollo-router/src/spec/query.rs | 192 +++++++- apollo-router/src/spec/query/tests.rs | 452 ++++++++++++++++++ ...__set_context_unrelated_fetch_failure.snap | 2 +- docs/source/errors.mdx | 9 + 6 files changed, 658 insertions(+), 16 deletions(-) create mode 100644 .changesets/fix_geal_response_validation_errors.md diff --git a/.changesets/fix_geal_response_validation_errors.md b/.changesets/fix_geal_response_validation_errors.md new file mode 100644 index 0000000000..95fc3d60eb --- /dev/null +++ b/.changesets/fix_geal_response_validation_errors.md @@ -0,0 +1,5 @@ +### add errors for response validation ([Issue #5372](https://github.com/apollographql/router/issues/5372)) + +When formatting responses, the router is validating the data returned by subgraphs and replacing it with null values as appropriate. That validation phase is now adding errors when encountering the wrong type in a field requested by the client. + +By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/5787 \ No newline at end of file diff --git a/apollo-router/src/json_ext.rs b/apollo-router/src/json_ext.rs index c9e617635f..54d1dd0bfe 100644 --- a/apollo-router/src/json_ext.rs +++ b/apollo-router/src/json_ext.rs @@ -146,6 +146,9 @@ pub(crate) trait ValueExt { #[track_caller] fn is_object_of_type(&self, schema: &Schema, maybe_type: &str) -> bool; + /// value type + fn json_type_name(&self) -> &'static str; + /// Convert this value to an instance of `apollo_compiler::ast::Value` fn to_ast(&self) -> apollo_compiler::ast::Value; @@ -475,6 +478,17 @@ impl ValueExt for Value { }) } + fn json_type_name(&self) -> &'static str { + match self { + Value::Array(_) => "array", + Value::Null => "null", + Value::Bool(_) => "boolean", + Value::Number(_) => "number", + Value::String(_) => "string", + Value::Object(_) => "object", + } + } + fn to_ast(&self) -> apollo_compiler::ast::Value { match self { Value::Null => apollo_compiler::ast::Value::Null, diff --git a/apollo-router/src/spec/query.rs b/apollo-router/src/spec/query.rs index 3ad855870a..c8bcddec6d 100644 --- a/apollo-router/src/spec/query.rs +++ b/apollo-router/src/spec/query.rs @@ -30,6 +30,7 @@ use crate::json_ext::Object; use crate::json_ext::Path; use crate::json_ext::ResponsePathElement; use crate::json_ext::Value; +use crate::json_ext::ValueExt; use crate::plugins::authorization::UnauthorizedPaths; use crate::query_planner::fetch::OperationKind; use crate::query_planner::fetch::QueryHash; @@ -51,6 +52,7 @@ pub(crate) mod transform; pub(crate) mod traverse; pub(crate) const TYPENAME: &str = "__typename"; +pub(crate) const RESPONSE_VALIDATION: &str = "RESPONSE_VALIDATION_FAILED"; /// A GraphQL query. #[derive(Derivative, Serialize, Deserialize)] @@ -143,8 +145,9 @@ impl Query { let mut parameters = FormatParameters { variables: &variables, schema, - errors: Vec::new(), + nullification_errors: Vec::new(), nullified: Vec::new(), + validation_errors: Vec::new(), }; response.data = Some( @@ -161,12 +164,18 @@ impl Query { }, ); - if !parameters.errors.is_empty() { - if let Ok(value) = serde_json_bytes::to_value(¶meters.errors) { + if !parameters.nullification_errors.is_empty() { + if let Ok(value) = + serde_json_bytes::to_value(¶meters.nullification_errors) + { response.extensions.insert("valueCompletion", value); } } + if !parameters.validation_errors.is_empty() { + response.errors.append(&mut parameters.validation_errors); + } + return parameters.nullified; } None => { @@ -198,8 +207,9 @@ impl Query { let mut parameters = FormatParameters { variables: &all_variables, schema, - errors: Vec::new(), + nullification_errors: Vec::new(), nullified: Vec::new(), + validation_errors: Vec::new(), }; response.data = Some( @@ -215,12 +225,18 @@ impl Query { Err(InvalidValue) => Value::Null, }, ); - if !parameters.errors.is_empty() { - if let Ok(value) = serde_json_bytes::to_value(¶meters.errors) { + if !parameters.nullification_errors.is_empty() { + if let Ok(value) = + serde_json_bytes::to_value(¶meters.nullification_errors) + { response.extensions.insert("valueCompletion", value); } } + if !parameters.validation_errors.is_empty() { + response.errors.append(&mut parameters.validation_errors); + } + return parameters.nullified; } } @@ -342,6 +358,7 @@ impl Query { output: &mut Value, path: &mut Vec>, parent_type: &executable::Type, + field_or_index: FieldOrIndex<'a>, selection_set: &'a [Selection], ) -> Result<(), InvalidValue> { // for every type, if we have an invalid value, we will replace it with null @@ -362,7 +379,8 @@ impl Query { input, output, path, - field_type, + parent_type, + field_or_index, selection_set, ) { Err(_) => Err(InvalidValue), @@ -377,7 +395,7 @@ impl Query { ), _ => todo!(), }; - parameters.errors.push(Error { + parameters.nullification_errors.push(Error { message, path: Some(Path::from_response_slice(path)), ..Error::default() @@ -417,6 +435,7 @@ impl Query { &mut output_array[i], path, field_type, + FieldOrIndex::Index(i), selection_set, ); path.pop(); @@ -430,7 +449,22 @@ impl Query { Ok(()) => Ok(()), } } - _ => Ok(()), + Value::Null => Ok(()), + v => { + parameters.validation_errors.push( + Error::builder() + .message(format!( + "Invalid non-list value of type {} for list type {field_type}", + v.json_type_name() + )) + .path(Path::from_response_slice(path)) + .extension_code(RESPONSE_VALIDATION) + .build(), + ); + + *output = Value::Null; + Ok(()) + } }, executable::Type::Named(name) if name == "Int" => { let opt = if input.is_i64() { @@ -446,6 +480,19 @@ impl Query { if opt.is_some() { *output = input.clone(); } else { + if !input.is_null() { + parameters.validation_errors.push( + Error::builder() + .message(invalid_value_message( + parent_type, + field_type, + field_or_index, + )) + .path(Path::from_response_slice(path)) + .extension_code(RESPONSE_VALIDATION) + .build(), + ); + } *output = Value::Null; } Ok(()) @@ -454,6 +501,19 @@ impl Query { if input.as_f64().is_some() { *output = input.clone(); } else { + if !input.is_null() { + parameters.validation_errors.push( + Error::builder() + .message(invalid_value_message( + parent_type, + field_type, + field_or_index, + )) + .path(Path::from_response_slice(path)) + .extension_code(RESPONSE_VALIDATION) + .build(), + ); + } *output = Value::Null; } Ok(()) @@ -462,6 +522,19 @@ impl Query { if input.as_bool().is_some() { *output = input.clone(); } else { + if !input.is_null() { + parameters.validation_errors.push( + Error::builder() + .message(invalid_value_message( + parent_type, + field_type, + field_or_index, + )) + .path(Path::from_response_slice(path)) + .extension_code(RESPONSE_VALIDATION) + .build(), + ); + } *output = Value::Null; } Ok(()) @@ -470,6 +543,19 @@ impl Query { if input.as_str().is_some() { *output = input.clone(); } else { + if !input.is_null() { + parameters.validation_errors.push( + Error::builder() + .message(invalid_value_message( + parent_type, + field_type, + field_or_index, + )) + .path(Path::from_response_slice(path)) + .extension_code(RESPONSE_VALIDATION) + .build(), + ); + } *output = Value::Null; } Ok(()) @@ -478,6 +564,19 @@ impl Query { if input.is_string() || input.is_i64() || input.is_u64() || input.is_f64() { *output = input.clone(); } else { + if !input.is_null() { + parameters.validation_errors.push( + Error::builder() + .message(invalid_value_message( + parent_type, + field_type, + field_or_index, + )) + .path(Path::from_response_slice(path)) + .extension_code(RESPONSE_VALIDATION) + .build(), + ); + } *output = Value::Null; } Ok(()) @@ -497,11 +596,31 @@ impl Query { *output = input.clone(); Ok(()) } else { + parameters.validation_errors.push( + Error::builder() + .message(format!( + "Expected a valid enum value for type {}", + enum_type.name + )) + .path(Path::from_response_slice(path)) + .extension_code(RESPONSE_VALIDATION) + .build(), + ); *output = Value::Null; Ok(()) } } None => { + parameters.validation_errors.push( + Error::builder() + .message(format!( + "Expected a valid enum value for type {}", + enum_type.name + )) + .path(Path::from_response_slice(path)) + .extension_code(RESPONSE_VALIDATION) + .build(), + ); *output = Value::Null; Ok(()) } @@ -512,6 +631,9 @@ impl Query { match input { Value::Object(ref mut input_object) => { + // FIXME: we should return an error if __typename is not a string + // but this might cause issues for some production deployments where + // __typename might be missing or invalid (cf https://github.com/apollographql/router/commit/4a592f4933b7b9e46f14c7a98404b9e067687f09 ) if let Some(input_type) = input_object.get(TYPENAME).and_then(|val| val.as_str()) { @@ -564,8 +686,20 @@ impl Query { Ok(()) } - _ => { - parameters.nullified.push(Path::from_response_slice(path)); + Value::Null => { + *output = Value::Null; + Ok(()) + } + v => { + parameters.validation_errors.push( + Error::builder() + .message(format!( + "Invalid non-object value of type {} for composite type {type_name}", v.json_type_name() + )) + .path(Path::from_response_slice(path)) + .extension_code(RESPONSE_VALIDATION) + .build(), + ); *output = Value::Null; Ok(()) } @@ -641,6 +775,7 @@ impl Query { output_value, path, current_type, + FieldOrIndex::Field(field_name.as_str()), selection_set, ); path.pop(); @@ -650,7 +785,7 @@ impl Query { output.insert((*field_name).clone(), Value::Null); } if field_type.is_non_null() { - parameters.errors.push(Error { + parameters.nullification_errors.push(Error { message: format!( "Cannot return null for non-nullable field {current_type}.{}", field_name.as_str() @@ -772,6 +907,11 @@ impl Query { continue; } + let root_type = apollo_compiler::ast::Type::Named( + // Unchecked name instantiation is always safe, and we know the name is + // valid here + apollo_compiler::Name::new_unchecked(root_type_name), + ); let field_name = alias.as_ref().unwrap_or(name); let field_name_str = field_name.as_str(); @@ -800,13 +940,14 @@ impl Query { input_value, output_value, path, - &field_type.0, + &root_type, + FieldOrIndex::Field(field_name_str), selection_set, ); path.pop(); res? } else if field_type.is_non_null() { - parameters.errors.push(Error { + parameters.nullification_errors.push(Error { message: format!( "Cannot return null for non-nullable field {}.{field_name_str}", root_type_name @@ -1014,7 +1155,8 @@ impl Query { /// Intermediate structure for arguments passed through the entire formatting struct FormatParameters<'a> { variables: &'a Object, - errors: Vec, + nullification_errors: Vec, + validation_errors: Vec, nullified: Vec, schema: &'a ApiSchema, } @@ -1034,6 +1176,26 @@ pub(crate) struct Variable { default_value: Option, } +enum FieldOrIndex<'a> { + Field(&'a str), + Index(usize), +} + +fn invalid_value_message( + parent_type: &executable::Type, + field_type: &executable::Type, + field_or_index: FieldOrIndex, +) -> String { + match field_or_index { + FieldOrIndex::Field(field_name) => { + format!("Invalid value found for field {parent_type}.{field_name}") + } + FieldOrIndex::Index(i) => { + format!("Invalid value found for array element of type {field_type} at index {i}") + } + } +} + impl Operation { fn empty() -> Self { Self { diff --git a/apollo-router/src/spec/query/tests.rs b/apollo-router/src/spec/query/tests.rs index 1d97962405..f9af994874 100644 --- a/apollo-router/src/spec/query/tests.rs +++ b/apollo-router/src/spec/query/tests.rs @@ -40,6 +40,7 @@ macro_rules! assert_eq_and_ordered_json { } #[derive(Default)] +#[must_use = "Must call .test() to run the test"] struct FormatTest { schema: Option<&'static str>, query_type_name: Option<&'static str>, @@ -100,6 +101,11 @@ impl FormatTest { self } + fn expected_errors(mut self, v: serde_json_bytes::Value) -> Self { + self.expected_errors = Some(v); + self + } + fn expected_extensions(mut self, v: serde_json_bytes::Value) -> Self { self.expected_extensions = Some(v); self @@ -1182,6 +1188,452 @@ fn reformat_response_array_of_id_duplicate() { .test(); } +#[test] +// If this test fails, this means you got greedy about allocations, +// beware of aliases! +fn reformat_response_expected_types() { + FormatTest::builder() + .schema( + "type Query { + get: Thing + } + type Thing { + i: Int + s: String + f: Float + b: Boolean + e: E + u: U + id: ID + l: [Int] + } + + enum E { + A + B + } + union U = ObjA | ObjB + type ObjA { + a: String + } + type ObjB { + a: String + } + ", + ) + .query( + r#"{ + get { + i + s + f + ... on Thing { + b + e + u { + ... on ObjA { + a + } + } + id + } + l + } + }"#, + ) + .response(json! {{ + "get": { + "i": "hello", + "s": 1.0, + "f": [1], + "b": 0, + "e": "X", + "u": 1, + "id": { + "test": "test", + }, + "l": "A" + }, + }}) + .expected(json! {{ + "get": { + "i": null, + "s": null, + "f": null, + "b": null, + "e": null, + "u": null, + // FIXME(@goto-bus-stop): this should be null, but we do not + // validate ID values today + "id": { + "test": "test", + }, + "l": null + }, + }}) + .expected_errors(json! ([ + { + "message": "Invalid value found for field Thing.i", + "path": ["get", "i"], + "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + }, + { + "message": "Invalid value found for field Thing.s", + "path": ["get", "s"], + "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + }, + { + "message": "Invalid value found for field Thing.f", + "path": ["get", "f"], + "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + }, + { + "message": "Invalid value found for field Thing.b", + "path": ["get", "b"], + "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + }, + { + "message": "Expected a valid enum value for type E", + "path": ["get", "e"], + "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + }, + { + "message": "Invalid non-object value of type number for composite type U", + "path": ["get", "u"], + "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + }, + { + "message": "Invalid non-list value of type string for list type [Int]", + "path": ["get", "l"], + "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + } + ])) + .test(); +} + +#[test] +fn reformat_response_expected_int() { + FormatTest::builder() + .schema( + r#" + type Query { + a: Int + b: Int + c: Int + d: Int + e: Int + f: Int + g: Int + } + "#, + ) + .query(r#"{ a b c d e f g }"#) + .response(json!({ + "a": 1, + "b": 1.0, // Should be accepted as Int 1 + "c": 1.2, // Float should not be truncated + "d": "1234", // Optional to be coerced by spec: we do not do so + "e": true, + "f": [1], + "g": { "value": 1 }, + })) + .expected(json!({ + "a": 1, + // FIXME(@goto-bus-stop): we should accept this, and truncate it + // to Int value `1`, but do not do so today + "b": null, + "c": null, + "d": null, + "e": null, + "f": null, + "g": null, + })) + .expected_errors(json!([ + { + "message": "Invalid value found for field Query.b", + "path": ["b"], + "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + }, + { + "message": "Invalid value found for field Query.c", + "path": ["c"], + "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + }, + { + "message": "Invalid value found for field Query.d", + "path": ["d"], + "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + }, + { + "message": "Invalid value found for field Query.e", + "path": ["e"], + "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + }, + { + "message": "Invalid value found for field Query.f", + "path": ["f"], + "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + }, + { + "message": "Invalid value found for field Query.g", + "path": ["g"], + "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + }, + ])) + .test(); +} + +#[test] +fn reformat_response_expected_int_range() { + let schema = "type Query { + me: User + } + + type User { + id: String! + name: String + someNumber: Int + someOtherNumber: Int! + } + "; + + let query = "query { me { id name someNumber } }"; + + FormatTest::builder() + .schema(schema) + .query(query) + .response(json!({ + "me": { + "id": "123", + "name": "Guy Guyson", + "someNumber": 51049694213_i64 + }, + })) + .expected(json!({ + "me": { + "id": "123", + "name": "Guy Guyson", + "someNumber": null, + }, + })) + .expected_errors(json!([ + { + "message": "Invalid value found for field User.someNumber", + "path": ["me", "someNumber"], + "extensions": { "code": "RESPONSE_VALIDATION_FAILED" }, + } + ])) + .test(); + + let query2 = "query { me { id name someOtherNumber } }"; + + FormatTest::builder() + .schema(schema) + .query(query2) + .response(json!({ + "me": { + "id": "123", + "name": "Guy Guyson", + "someOtherNumber": 51049694213_i64 + }, + })) + .expected(json!({ + "me": null, + })) + .expected_errors(json!([ + { + "message": "Invalid value found for field User.someOtherNumber", + "path": ["me", "someOtherNumber"], + "extensions": { "code": "RESPONSE_VALIDATION_FAILED" }, + }, + ])) + .test(); +} + +#[test] +fn reformat_response_expected_float() { + FormatTest::builder() + .schema( + r#" + type Query { + a: Float + b: Float + c: Float + d: Float + e: Float + f: Float + } + "#, + ) + .query(r#"{ a b c d e f }"#) + .response(json!({ + // Note: NaNs and Infinitys are not supported by GraphQL Floats, + // and handily not representable in JSON, so we don't need to handle them. + "a": 1, // Int can be interpreted as Float + "b": 1.2, + "c": "2.2", // Optional to be coerced by spec: we do not do so + "d": true, + "e": [1.234], + "f": { "value": 12.34 }, + })) + .expected(json!({ + "a": 1, // Representing int-valued float without the decimals is okay in JSON + "b": 1.2, + "c": null, + "d": null, + "e": null, + "f": null, + })) + .expected_errors(json!([ + { + "message": "Invalid value found for field Query.c", + "path": ["c"], + "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + }, + { + "message": "Invalid value found for field Query.d", + "path": ["d"], + "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + }, + { + "message": "Invalid value found for field Query.e", + "path": ["e"], + "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + }, + { + "message": "Invalid value found for field Query.f", + "path": ["f"], + "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + }, + ])) + .test(); +} + +#[test] +fn reformat_response_expected_string() { + FormatTest::builder() + .schema( + r#" + type Query { + a: String + b: String + c: String + d: String + e: String + f: String + } + "#, + ) + .query(r#"{ a b c d e f }"#) + .response(json!({ + "a": "text", + "b": 1, // Optional to be coerced by spec: we do not do so + "c": false, // Optional to be coerced by spec: we do not do so + "d": 1234.5678, // Optional to be coerced by spec: we do not do so + "e": ["s"], + "f": { "text": "text" }, + })) + .expected(json!({ + "a": "text", + "b": null, + "c": null, + "d": null, + "e": null, + "f": null, + })) + .expected_errors(json!([ + { + "message": "Invalid value found for field Query.b", + "path": ["b"], + "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + }, + { + "message": "Invalid value found for field Query.c", + "path": ["c"], + "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + }, + { + "message": "Invalid value found for field Query.d", + "path": ["d"], + "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + }, + { + "message": "Invalid value found for field Query.e", + "path": ["e"], + "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + }, + { + "message": "Invalid value found for field Query.f", + "path": ["f"], + "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + }, + ])) + .test(); +} + +#[test] +fn reformat_response_expected_id() { + FormatTest::builder() + .schema( + r#" + type Query { + a: ID + b: ID + c: ID + d: ID + e: ID + f: ID + g: ID + } + "#, + ) + .query(r#"{ a b c d e f g }"#) + .response(json!({ + "a": "1234", + "b": "ABCD", + "c": 1234, + "d": 1234.0, // Integer represented as a float should be coerced + "e": false, + "f": 1234.5678, // Float should not be truncated + "g": ["s"], + })) + .expected(json!({ + // Note technically IDs should always be represented as a String in JSON, + // though the value returned from a field can be either Int or String. + // We do not coerce the acceptable types to strings today. + "a": "1234", + "b": "ABCD", + "c": 1234, + // FIXME(@goto-bus-stop): We should coerce this to string "1234" (without .0), + // but we don't do so today + "d": 1234.0, + // FIXME(@goto-bus-stop): We should null out all these values, + // but we don't validate IDs today + "e": false, + "f": 1234.5678, + "g": ["s"], + })) + .expected_errors(json!([ + // FIXME(@goto-bus-stop): we should expect these errors: + // { + // "message": "Invalid value found for field Query.e", + // "path": ["e"], + // "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + // }, + // { + // "message": "Invalid value found for field Query.f", + // "path": ["f"], + // "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + // }, + // { + // "message": "Invalid value found for field Query.g", + // "path": ["g"], + // "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } + // }, + ])) + .test(); +} + #[test] fn solve_query_with_single_typename() { FormatTest::builder() diff --git a/apollo-router/tests/snapshots/set_context__set_context_unrelated_fetch_failure.snap b/apollo-router/tests/snapshots/set_context__set_context_unrelated_fetch_failure.snap index 49dcf6bf9b..4f28e80419 100644 --- a/apollo-router/tests/snapshots/set_context__set_context_unrelated_fetch_failure.snap +++ b/apollo-router/tests/snapshots/set_context__set_context_unrelated_fetch_failure.snap @@ -160,7 +160,7 @@ expression: response ] }, { - "message": "Cannot return null for non-nullable field T!.t", + "message": "Cannot return null for non-nullable field Query.t", "path": [ "t" ] diff --git a/docs/source/errors.mdx b/docs/source/errors.mdx index 5730dd6fef..497471d8d9 100644 --- a/docs/source/errors.mdx +++ b/docs/source/errors.mdx @@ -99,4 +99,13 @@ The query could not be parsed. The response from a subgraph did not match the GraphQL schema. + + + + +A subgraph returned a field with a different type that mandated by the GraphQL schema. + + + + From f2dc704d69f11ccbfdbf2e5198547f17ba9e61b9 Mon Sep 17 00:00:00 2001 From: timbotnik Date: Tue, 29 Oct 2024 22:21:10 +1100 Subject: [PATCH 15/77] Apply suggestions from code review Co-authored-by: Edward Huang --- docs/source/configuration/overview.mdx | 8 ++-- .../telemetry/apollo-telemetry.mdx | 47 ++++++++++--------- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/docs/source/configuration/overview.mdx b/docs/source/configuration/overview.mdx index c96db9d4fc..2d0ec9af30 100644 --- a/docs/source/configuration/overview.mdx +++ b/docs/source/configuration/overview.mdx @@ -873,11 +873,11 @@ You won't see an immediate change in checks behavior when you first turn on exte -Beginning in v1.49.0, the router supports sending traces to Studio via the more detailed OTel (OpenTelemetry) protocol. -Support for OTel traces has historically only been available for 3rd party APM tools. With this option, -Studio can now provide a much more granular view of Router internals than the legacy Apollo tracing protocol. +Beginning in v1.49.0, the router supports sending traces to Studio via the OpenTelemetry Protocol (OTLP). +Support for OTLP traces has historically only been available for third-party APM tools. With this option, +Studio can now provide a much more granular and detailed view of router internals than the previous Apollo tracing protocol. -See [Enhanced tracing in Studio via OTel](./telemetry/apollo-telemetry#enhanced-tracing-in-studio-via-opentelemetry). +To learn more, see [Enhanced tracing in Studio via OpenTelemetry](./telemetry/apollo-telemetry#enhanced-tracing-in-studio-via-opentelemetry). ### Safelisting with persisted queries diff --git a/docs/source/configuration/telemetry/apollo-telemetry.mdx b/docs/source/configuration/telemetry/apollo-telemetry.mdx index d4e276118e..20070898ce 100644 --- a/docs/source/configuration/telemetry/apollo-telemetry.mdx +++ b/docs/source/configuration/telemetry/apollo-telemetry.mdx @@ -80,30 +80,34 @@ telemetry: -Beginning in v1.49.0, the router supports sending traces to Studio via the more detailed OTel (OpenTelemetry) protocol. +Beginning in v1.49.0, the router supports sending traces to Studio via the OpenTelemetry protocol (OTLP). +Support for OTLP traces has historically only been available for third-party APM tools. With this option, +Studio can now provide a much more granular and detailed view of router internals than the previous Apollo tracing protocol. Support for OTel traces has historically only been available for 3rd party APM tools. With this option, Studio can now provide a much more granular view of Router internals than the legacy Apollo tracing protocol. -Benefits include: +Benefits of OTLP traces include: -- A comprehensive way to visualize the Router execution path in Studio. -- Additional spans that were previously not included in Studio traces, such as query parsing, planning, execution, and more. -- Additional attributes including HTTP request details, REST connector details, and more. +- Comprehensive visualization of the router execution path in Studio +- New spans in Studio traces, including query parsing, planning, execution, and more +- New attributes, including HTTP request details, REST connector details, and more -It is expected that this will become the default in a future version of Router. #### Configuration -This change adds a new configuration option `telemetry.apollo.experimental_otlp_tracing_sampler`. Use this option to send +You can configure OTel traces with the `telemetry.apollo.experimental_otlp_tracing_sampler` option. Use this option to send a percentage of traces to Studio via OTLP instead of the native Apollo Usage Reporting protocol. Supported values: -- `always_off` (default): send all traces via the legacy Apollo Usage Reporting protocol. -- `always_on`: send all traces via OTLP. -- `0.0 - 1.0` (used for testing): the ratio of traces to send via OTLP (0.5 = 50 / 50). +- `always_off` (default): send all traces via the legacy Apollo Usage Reporting protocol +- `always_on`: send all traces via OTLP +- `0.0 - 1.0` (used for testing): the ratio of traces to send via OTLP (0.4 = 40% OTLP / 60% legacy) -Note that this sampler is only applied _after_ the common tracing sampler, for example: +This sampler is applied after the common tracing sampler. + +#### Example configuration + +An example configuration that samples 1% of traces and sends all traces via OTLP: -#### Sample 1% of traces, send all traces via OTLP: ```yaml telemetry: @@ -118,21 +122,18 @@ telemetry: sampler: 0.01 ``` -OTel traces sent to Studio will not necessarily be identical to the ones sent to 3rd Party APM tools via OTLP: +OTLP traces sent to Studio aren't necessarily identical to ones sent to third-party APM tools via OTLP: -- Only specific OTLP attributes will be included for parity with what is provided in legacy traces today. This ensures that data privacy - is maintained in an equivalent manner. The existing Router configuration options for Apollo telemetry will continue to function - with OTLP traces, such as forwarding of GraphQL errors, headers, and variables. -- Some features of OTLP traces may only be available in Studio and not in 3rd Party APM tools (e.g. resolver-level timing information from - [Federated Tracing](../../federation/metrics/#enabling-federated-tracing)). +- Only specific OTLP attributes are included for parity with legacy traces today. This ensures that data privacy is maintained in an equivalent manner. Existing router configuration options for Apollo telemetry will continue to function with OTLP traces, including forwarding of GraphQL errors, headers, and variables. +- Some features of OTLP traces are available only in Studio and not in third-party APM tools, such as resolver-level timing information from [Federated Tracing](../../federation/metrics/#enabling-federated-tracing) -This change results in using a new wire protocol for traces, and some users may experience an increase in tracing traffic -to GraphOS Studio due to the additional detail being captured. In exceptional situations it may be necessary to send fewer traces. -This can be achieved via sending fewer traces (`telemetry.exporters.tracing.common.sampler`) or as a last resort, falling back -to the old protocol via `telemetry.apollo.otlp_tracing_sampler` to send fewer OTLP traces or fully disable them. -Any performance regressions due to the new tracing protocol should also be reported to the Apollo support team. +You may experience an increase in tracing traffic sent to GraphOS Studio due to the additional detail captured by the new wire protocol. In exceptional situations, you may need to send fewer traces. + +To send fewer traces, configure `telemetry.exporters.tracing.common.sampler` or revert to the old protocol via `telemetry.apollo.otlp_tracing_sampler` to send fewer OTLP traces or to disable them. + +For performance regressions due to the new tracing protocol, you should report them to the [Apollo support team](https://www.apollographql.com/support). From 442a543e8078eec7e0c0015e8111f5a939c6f00a Mon Sep 17 00:00:00 2001 From: timbotnik Date: Tue, 29 Oct 2024 23:37:19 +1100 Subject: [PATCH 16/77] Update docs/source/configuration/telemetry/apollo-telemetry.mdx Co-authored-by: Coenen Benjamin --- docs/source/configuration/telemetry/apollo-telemetry.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/configuration/telemetry/apollo-telemetry.mdx b/docs/source/configuration/telemetry/apollo-telemetry.mdx index 20070898ce..4c2fb8d04f 100644 --- a/docs/source/configuration/telemetry/apollo-telemetry.mdx +++ b/docs/source/configuration/telemetry/apollo-telemetry.mdx @@ -109,7 +109,7 @@ This sampler is applied after the common tracing sampler. An example configuration that samples 1% of traces and sends all traces via OTLP: -```yaml +```yaml title="router.config.yaml" telemetry: apollo: # Send all traces via OTLP From aa8bdd074e1be3449b62d899652583a5a839c93d Mon Sep 17 00:00:00 2001 From: Coenen Benjamin Date: Wed, 30 Oct 2024 10:18:25 +0100 Subject: [PATCH 17/77] Remove summit ad (#6209) --- README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/README.md b/README.md index 0f87d6d343..df19eb7593 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,6 @@ --- -**Announcement:** -Join 1000+ engineers at GraphQL Summit for talks, workshops, and office hours, Oct 8-10 in NYC. [Get your pass here ->](https://summit.graphql.com/?utm_campaign=github_federation_readme) - ---- - # Apollo Router Core The **Apollo Router Core** is a configurable, high-performance **graph router** written in Rust to run a [federated supergraph](https://www.apollographql.com/docs/federation/) that uses [Apollo Federation 2](https://www.apollographql.com/docs/federation/v2/federation-2/new-in-federation-2). From f8e9a5200e282c0fa872780e75aca88b723cd42b Mon Sep 17 00:00:00 2001 From: Coenen Benjamin Date: Wed, 30 Oct 2024 16:39:42 +0100 Subject: [PATCH 18/77] chore(telemetry): don't create a stub span for supergraph events if it already has a current span (#6096) Signed-off-by: Benjamin <5719034+bnjjj@users.noreply.github.com> --- .changesets/maint_bnjjj_fix_supergraph_events_span.md | 5 +++++ .../src/plugins/telemetry/config_new/events.rs | 10 +++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) create mode 100644 .changesets/maint_bnjjj_fix_supergraph_events_span.md diff --git a/.changesets/maint_bnjjj_fix_supergraph_events_span.md b/.changesets/maint_bnjjj_fix_supergraph_events_span.md new file mode 100644 index 0000000000..00f5cf241d --- /dev/null +++ b/.changesets/maint_bnjjj_fix_supergraph_events_span.md @@ -0,0 +1,5 @@ +### Don't create a stub span for supergraph events if it already has a current span ([PR #6096](https://github.com/apollographql/router/pull/6096)) + +Don't create useless span when we already have a span available to use the span's extensions. + +By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/6096 \ No newline at end of file diff --git a/apollo-router/src/plugins/telemetry/config_new/events.rs b/apollo-router/src/plugins/telemetry/config_new/events.rs index a58264bfb7..c5fac133a2 100644 --- a/apollo-router/src/plugins/telemetry/config_new/events.rs +++ b/apollo-router/src/plugins/telemetry/config_new/events.rs @@ -741,9 +741,13 @@ where } // Stub span to make sure the custom attributes are saved in current span extensions // It won't be extracted or sampled at all - let span = info_span!("supergraph_event_send_event"); - let _entered = span.enter(); - inner.send_event(attributes); + if Span::current().is_none() { + let span = info_span!("supergraph_event_send_event"); + let _entered = span.enter(); + inner.send_event(attributes); + } else { + inner.send_event(attributes); + } } fn on_error(&self, error: &BoxError, ctx: &Context) { From bc7472e06b6d8ace64d4f4fbd6607da9d0e2674a Mon Sep 17 00:00:00 2001 From: Geoffroy Couprie Date: Thu, 31 Oct 2024 15:34:25 +0100 Subject: [PATCH 19/77] do not count the wait time in deduplication as processing time (#6207) --- .changesets/fix_geal_deduplication_processing_time.md | 5 +++++ apollo-router/src/plugins/traffic_shaping/deduplication.rs | 1 + 2 files changed, 6 insertions(+) create mode 100644 .changesets/fix_geal_deduplication_processing_time.md diff --git a/.changesets/fix_geal_deduplication_processing_time.md b/.changesets/fix_geal_deduplication_processing_time.md new file mode 100644 index 0000000000..a3a75c467e --- /dev/null +++ b/.changesets/fix_geal_deduplication_processing_time.md @@ -0,0 +1,5 @@ +### do not count the wait time in deduplication as processing time ([PR #6207](https://github.com/apollographql/router/pull/6207)) + +waiting for a deduplicated request was incorrectly counted as time spent in the router overhead, while most of it was actually spent waiting for the subgraph response. + +By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/6207 \ No newline at end of file diff --git a/apollo-router/src/plugins/traffic_shaping/deduplication.rs b/apollo-router/src/plugins/traffic_shaping/deduplication.rs index 0df2574eb4..5c2165f775 100644 --- a/apollo-router/src/plugins/traffic_shaping/deduplication.rs +++ b/apollo-router/src/plugins/traffic_shaping/deduplication.rs @@ -98,6 +98,7 @@ where let mut receiver = waiter.subscribe(); drop(locked_wait_map); + let _guard = request.context.enter_active_request(); match receiver.recv().await { Ok(value) => { return value From 6f65fa4913e84e9c3113791a358cb00dc2b689e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e?= Date: Mon, 4 Nov 2024 08:58:48 +0000 Subject: [PATCH 20/77] Remove redundant clone (#6218) --- apollo-router/src/services/layers/query_analysis.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apollo-router/src/services/layers/query_analysis.rs b/apollo-router/src/services/layers/query_analysis.rs index ce008c0a0f..4af57a5f38 100644 --- a/apollo-router/src/services/layers/query_analysis.rs +++ b/apollo-router/src/services/layers/query_analysis.rs @@ -205,7 +205,7 @@ impl QueryAnalysisLayer { doc.executable.clone(), op_name, self.schema.api_schema(), - &request.supergraph_request.body().variables.clone(), + &request.supergraph_request.body().variables, )) } else { None From 284af97f05c4b0f18b13114dbfecd940ccb12c8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e?= Date: Tue, 5 Nov 2024 12:50:56 +0000 Subject: [PATCH 21/77] chore(federation): update outdated comments in QueryPlannerConfig (#6229) --- .../src/query_plan/query_planner.rs | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/apollo-federation/src/query_plan/query_planner.rs b/apollo-federation/src/query_plan/query_planner.rs index 24e0972944..1a3f1002f1 100644 --- a/apollo-federation/src/query_plan/query_planner.rs +++ b/apollo-federation/src/query_plan/query_planner.rs @@ -56,31 +56,26 @@ pub(crate) const CONTEXT_DIRECTIVE: &str = "context"; #[derive(Debug, Clone, Hash)] pub struct QueryPlannerConfig { - /// Whether the query planner should try to reused the named fragments of the planned query in + /// Whether the query planner should try to reuse the named fragments of the planned query in /// subgraph fetches. /// - /// This is often a good idea as it can prevent very large subgraph queries in some cases (named - /// fragments can make some relatively small queries (using said fragments) expand to a very large - /// query if all the spreads are inline). However, due to architecture of the query planner, this - /// optimization is done as an additional pass on the subgraph queries of the generated plan and - /// can thus increase the latency of building a plan. As long as query plans are sufficiently - /// cached, this should not be a problem, which is why this option is enabled by default, but if - /// the distribution of inbound queries prevents efficient caching of query plans, this may become - /// an undesirable trade-off and can be disabled in that case. + /// Reusing fragments requires complicated validations, so it can take a long time on large + /// queries with many fragments. This option may be removed in the future in favour of + /// [`generate_query_fragments`][QueryPlannerConfig::generate_query_fragments]. /// /// Defaults to true. pub reuse_query_fragments: bool, - /// NOTE: **not implemented yet** - /// /// If enabled, the query planner will extract inline fragments into fragment /// definitions before sending queries to subgraphs. This can significantly - /// reduce the size of the query sent to subgraphs, but may increase the time - /// it takes to plan the query. + /// reduce the size of the query sent to subgraphs. /// /// Defaults to false. pub generate_query_fragments: bool, + /// **TODO:** This option is not implemented, and the behaviour is *always enabled*. + /// + /// /// Whether to run GraphQL validation against the extracted subgraph schemas. Recommended in /// non-production settings or when debugging. /// @@ -112,8 +107,8 @@ impl Default for QueryPlannerConfig { fn default() -> Self { Self { reuse_query_fragments: true, - subgraph_graphql_validation: false, generate_query_fragments: false, + subgraph_graphql_validation: false, incremental_delivery: Default::default(), debug: Default::default(), type_conditioned_fetching: Default::default(), @@ -123,12 +118,15 @@ impl Default for QueryPlannerConfig { #[derive(Debug, Clone, Default, Hash)] pub struct QueryPlanIncrementalDeliveryConfig { - /// Enables @defer support by the query planner. + /// Enables `@defer` support in the query planner, breaking up the query plan with [DeferNode]s + /// as appropriate. + /// + /// If false, operations with `@defer` are still accepted, but are planned as if they did not + /// contain `@defer` directives. /// - /// If set, then the query plan for queries having some @defer will contains some `DeferNode` - /// (see `query_plan/mod.rs`). + /// Defaults to false. /// - /// Defaults to false (meaning that the @defer are ignored). + /// [DeferNode]: crate::query_plan::DeferNode pub enable_defer: bool, } From a8ba72620ee29a0c729b446be76b5b4cdc544c04 Mon Sep 17 00:00:00 2001 From: Maria Elisabeth Schreiber Date: Tue, 5 Nov 2024 08:57:54 -0700 Subject: [PATCH 22/77] docs: correct authorization directive composition (#6216) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Renรฉe --- ...ify_authorization_directive_composition.md | 5 ++ docs/source/configuration/authorization.mdx | 53 ++++++++++++------- docs/source/errors.mdx | 5 +- 3 files changed, 42 insertions(+), 21 deletions(-) create mode 100644 .changesets/docs_clarify_authorization_directive_composition.md diff --git a/.changesets/docs_clarify_authorization_directive_composition.md b/.changesets/docs_clarify_authorization_directive_composition.md new file mode 100644 index 0000000000..52d0610cc9 --- /dev/null +++ b/.changesets/docs_clarify_authorization_directive_composition.md @@ -0,0 +1,5 @@ +### docs: correct authorization directive composition ([PR #6216](https://github.com/apollographql/router/pull/6216)) + +Make authorization directive composition clearer and correct code examples + +By [@Meschreiber](https://github.com/Meschreiber) in https://github.com/apollographql/router/pull/6216 diff --git a/docs/source/configuration/authorization.mdx b/docs/source/configuration/authorization.mdx index cd241d1d4a..f31e4e4226 100644 --- a/docs/source/configuration/authorization.mdx +++ b/docs/source/configuration/authorization.mdx @@ -688,12 +688,12 @@ When using subscriptions along with `@policy` authorization, subscription events ## Composition and federation -GraphOS's composition strategy for authorization directives is intentionally accumulative. When you define authorization directives on fields and types in subgraphs, GraphOS composes them into the supergraph schema. In other words, if subgraph fields or types include `@requiresScopes`, `@authenticated`, or `@policy` directives, they are set on the supergraph too. +GraphOS's composition strategy for authorization directives is intentionally accumulative. When you define authorization directives on fields and types in subgraphs, GraphOS composes them into the supergraph schema. In other words, if subgraph fields or types include `@requiresScopes`, `@authenticated`, or `@policy` directives, they are set on the supergraph too. Whether composition uses `AND` or `OR` logic depends on how the authorization directives are used. -#### Composition with `AND`/`OR` logic - -If shared subgraph fields include multiple directives, composition merges them. For example, suppose the `me` query requires `@authentication` in one subgraph: +### Composed fields with different authorization directives +If a shared field uses different authorization directives across subgraphs, composition merges them using `AND` logic. +For example, suppose the `me` query requires `@authenticated` in one subgraph and the `read:user` scope in another subgraph: ```graphql title="Subgraph A" type Query { @@ -707,8 +707,6 @@ type User { } ``` -and the `read:user` scope in another subgraph: - ```graphql title="Subgraph B" type Query { me: User @requiresScopes(scopes: [["read:user"]]) @@ -721,9 +719,19 @@ type User { } ``` -A request would need to both be authenticated **AND** have the required scope. Recall that the `@authenticated` directive only checks for the existence of the `apollo_authentication::JWT::claims` key in a request's context, so authentication is guaranteed if the request includes scopes. +A request must both be authenticated **AND** have the required `read:user` scope to succeed. + + + +Recall that the `@authenticated` directive only checks for the existence of the `apollo_authentication::JWT::claims` key in a request's context, so authentication is guaranteed if the request includes scopes. + + + +### Composed fields with the same authorization directives -If multiple shared subgraph fields include `@requiresScopes`, the supergraph schema merges them with the same logic used to [combine scopes for a single use of `@requiresScopes`](#combining-required-scopes-with-andor-logic). For example, if one subgraph requires the `read:others` scope on the `users` query: +If a shared field uses the same authorization directives across subgraphs, composition merges them using `OR` logic. +For example, suppose two subgraphs use the `@requiresScopes` directive on the `users` query. +One subgraph requires the `read:others` scope, and another subgraph requires the `read:profiles` scope: ```graphql title="Subgraph A" type Query { @@ -731,23 +739,32 @@ type Query { } ``` -and another subgraph requires the `read:profiles` scope on `users` query: - ```graphql title="Subgraph B" type Query { users: [User!]! @requiresScopes(scopes: [["read:profiles"]]) } ``` -Then the supergraph schema would require _both_ scopes for it. +A request would need either the `read:others` **OR** the `read:profiles` scope to be authorized. ```graphql title="Supergraph" type Query { - users: [User!]! @requiresScopes(scopes: [["read:others", "read:profiles"]]) + users: [User!]! @requiresScopes(scopes: [["read:others"], ["read:profiles"]]) } ``` -As with [combining scopes for a single use of `@requiresScopes`](#combining-required-scopes-with-andor-logic), you can use nested arrays to introduce **OR** logic: + + +Refer to the section on [Combining policies with AND/OR logic](#combining-policies-with-andor-logic) for a refresher of `@requiresScopes` boolean syntax. + + + +Using **OR** logic for shared directives simplifies schema updates. +If requirements change suddenly, you don't need to update the directive in all subgraphs simultaneously. + +#### Combining `AND`/`OR` logic with `@requiresScopes` + +As with [combining scopes for a single use of [`@requiresScopes`](#combining-required-scopes-with-andor-logic), you can use nested arrays to introduce **AND** logic in a single subgraph: ```graphql title="Subgraph A" type Query { @@ -761,7 +778,7 @@ type Query { } ``` -Since both `scopes` arrays are nested arrays, they would be composed using **OR** logic into the supergraph schema: +Since both subgraphs use the same authorization directive, composition [merges them using **OR** logic](#a-shared-field-with-the-same-authorization-directives-use-or-logic): ```graphql title="Supergraph" type Query { @@ -773,8 +790,8 @@ This syntax means a request needs either (`read:others` **AND** `read:users`) sc ### Authorization and `@key` fields -The [`@key` directive](https://www.apollographql.com/docs/federation/entities/) lets you create an entity whose fields resolve across multiple subgraphs. -If you use authorization directives on fields defined in [`@key` directives](https://www.apollographql.com/docs/federation/entities/), Apollo still uses those fields to compose entities between the subgraphs, but the client cannot query them directly. +The [`@key` directive](/graphos/reference/federation/directives#key) lets you create an entity whose fields resolve across multiple subgraphs. +If you use authorization directives on fields defined in `@key` directives, Apollo still uses those fields to compose entities between the subgraphs, but the client cannot query them directly. Consider these example subgraph schemas: @@ -825,11 +842,11 @@ query { } ``` -This behavior resembles what you can create with [contracts](/graphos/delivery/contracts/) and the [`@inaccessible` directive](https://www.apollographql.com/docs/federation/federated-types/federated-directives/#inaccessible). +This behavior resembles what you can create with [contracts](/graphos/delivery/contracts/) and the [`@inaccessible` directive](/graphos/reference/federation/directives#inaccessible). ### Authorization and interfaces -If a type [implementing an interface](https://www.apollographql.com/docs/apollo-server/schema/unions-interfaces/#interface-type) requires authorization, unauthorized requests can query the interface, but not any parts of the type that require authorization. +If a type [implementing an interface](/apollo-server/schema/unions-interfaces/#interface-type) requires authorization, unauthorized requests can query the interface, but not any parts of the type that require authorization. For example, consider this schema where the `Post` interface doesn't require authentication, but the `PrivateBlog` type, which implements `Post`, does: diff --git a/docs/source/errors.mdx b/docs/source/errors.mdx index 497471d8d9..aa4bd41c88 100644 --- a/docs/source/errors.mdx +++ b/docs/source/errors.mdx @@ -94,14 +94,13 @@ The actual cost of the query was greater than the configured maximum cost. The query could not be parsed. - + The response from a subgraph did not match the GraphQL schema. - - + A subgraph returned a field with a different type that mandated by the GraphQL schema. From 36bdb5e8ee83c4d248d20611dd68be9e9f219e1d Mon Sep 17 00:00:00 2001 From: Geoffroy Couprie Date: Tue, 5 Nov 2024 17:23:45 +0100 Subject: [PATCH 23/77] Query planner cache key improvements (#6206) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix #5160 This splits part of the work from #5255 to make it easier to merge. This covers improvements and fixes to the query planner cache key from changes related to the query hashing algorithm and query plan reuse during warmup. Fixed: * use prefixes for each part of the redis cache key so they become self describing * remove the custom Hash implementation for the cache key * remove JSON serialization * hash the Rust planner's config only once, not on every cache query Co-authored-by: Ivan Goncharov Co-authored-by: Jeremy Lempereur Co-authored-by: Gary Pennington Co-authored-by: Jesse Rosenberger Co-authored-by: Renรฉe --- ...al_query_planner_cache_key_improvements.md | 8 ++ apollo-router/src/configuration/mod.rs | 16 +++ .../query_planner/caching_query_planner.rs | 99 ++++++++++++------- apollo-router/tests/integration/redis.rs | 12 +-- 4 files changed, 94 insertions(+), 41 deletions(-) create mode 100644 .changesets/maint_geal_query_planner_cache_key_improvements.md diff --git a/.changesets/maint_geal_query_planner_cache_key_improvements.md b/.changesets/maint_geal_query_planner_cache_key_improvements.md new file mode 100644 index 0000000000..720836429f --- /dev/null +++ b/.changesets/maint_geal_query_planner_cache_key_improvements.md @@ -0,0 +1,8 @@ +### Query planner cache key improvements ([Issue #5160](https://github.com/apollographql/router/issues/5160)) + +> [!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. + +This brings several performance improvements to the query plan cache key generation. In particular, it changes the distributed cache's key format, adding prefixes to the different key segments, to help in debugging. + +By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/6206 \ No newline at end of file diff --git a/apollo-router/src/configuration/mod.rs b/apollo-router/src/configuration/mod.rs index 00657cc11d..85de05cd8f 100644 --- a/apollo-router/src/configuration/mod.rs +++ b/apollo-router/src/configuration/mod.rs @@ -412,6 +412,22 @@ impl Configuration { type_conditioned_fetching: self.experimental_type_conditioned_fetching, } } + + pub(crate) fn rust_query_planner_config( + &self, + ) -> apollo_federation::query_plan::query_planner::QueryPlannerConfig { + apollo_federation::query_plan::query_planner::QueryPlannerConfig { + reuse_query_fragments: self.supergraph.reuse_query_fragments.unwrap_or(true), + subgraph_graphql_validation: false, + generate_query_fragments: self.supergraph.generate_query_fragments, + incremental_delivery: + apollo_federation::query_plan::query_planner::QueryPlanIncrementalDeliveryConfig { + enable_defer: self.supergraph.defer_support, + }, + type_conditioned_fetching: self.experimental_type_conditioned_fetching, + debug: Default::default(), + } + } } impl Default for Configuration { diff --git a/apollo-router/src/query_planner/caching_query_planner.rs b/apollo-router/src/query_planner/caching_query_planner.rs index 6ef9a671e8..688ce1c697 100644 --- a/apollo-router/src/query_planner/caching_query_planner.rs +++ b/apollo-router/src/query_planner/caching_query_planner.rs @@ -1,5 +1,6 @@ use std::collections::HashMap; use std::hash::Hash; +use std::hash::Hasher; use std::ops::Deref; use std::sync::Arc; use std::task; @@ -14,7 +15,6 @@ use router_bridge::planner::PlanOptions; use router_bridge::planner::Planner; use router_bridge::planner::QueryPlannerConfig; use router_bridge::planner::UsageReporting; -use serde::Serialize; use sha2::Digest; use sha2::Sha256; use tower::BoxError; @@ -57,11 +57,11 @@ pub(crate) type InMemoryCachePlanner = InMemoryCache>>; pub(crate) const APOLLO_OPERATION_ID: &str = "apollo_operation_id"; -#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize)] +#[derive(Debug, Clone, Hash)] pub(crate) enum ConfigMode { //FIXME: add the Rust planner structure once it is hashable and serializable, // for now use the JS config as it expected to be identical to the Rust one - Rust(Arc), + Rust(Arc), Both(Arc), BothBestEffort(Arc), Js(Arc), @@ -80,7 +80,7 @@ pub(crate) struct CachingQueryPlanner { subgraph_schemas: Arc>>>, plugins: Arc, enable_authorization_directives: bool, - config_mode: ConfigMode, + config_mode_hash: Arc, } fn init_query_plan_from_redis( @@ -125,20 +125,34 @@ where let enable_authorization_directives = AuthorizationPlugin::enable_directives(configuration, &schema).unwrap_or(false); - let config_mode = match configuration.experimental_query_planner_mode { + let mut hasher = StructHasher::new(); + match configuration.experimental_query_planner_mode { crate::configuration::QueryPlannerMode::New => { - ConfigMode::Rust(Arc::new(configuration.js_query_planner_config())) + "PLANNER-NEW".hash(&mut hasher); + ConfigMode::Rust(Arc::new(configuration.rust_query_planner_config())) + .hash(&mut hasher); } crate::configuration::QueryPlannerMode::Legacy => { - ConfigMode::Js(Arc::new(configuration.js_query_planner_config())) + "PLANNER-LEGACY".hash(&mut hasher); + ConfigMode::Js(Arc::new(configuration.js_query_planner_config())).hash(&mut hasher); } crate::configuration::QueryPlannerMode::Both => { + "PLANNER-BOTH".hash(&mut hasher); ConfigMode::Both(Arc::new(configuration.js_query_planner_config())) + .hash(&mut hasher); + ConfigMode::Rust(Arc::new(configuration.rust_query_planner_config())) + .hash(&mut hasher); } crate::configuration::QueryPlannerMode::BothBestEffort => { + "PLANNER-BOTH-BEST-EFFORT".hash(&mut hasher); ConfigMode::BothBestEffort(Arc::new(configuration.js_query_planner_config())) + .hash(&mut hasher); + ConfigMode::Rust(Arc::new(configuration.rust_query_planner_config())) + .hash(&mut hasher); } }; + let config_mode_hash = Arc::new(QueryHash(hasher.finalize())); + Ok(Self { cache, delegate, @@ -146,7 +160,7 @@ where subgraph_schemas, plugins: Arc::new(plugins), enable_authorization_directives, - config_mode, + config_mode_hash, }) } @@ -204,7 +218,7 @@ where hash: Some(hash.clone()), metadata: metadata.clone(), plan_options: plan_options.clone(), - config_mode: self.config_mode.clone(), + config_mode: self.config_mode_hash.clone(), }, ) .take(count) @@ -249,7 +263,7 @@ where hash: None, metadata: CacheKeyMetadata::default(), plan_options: PlanOptions::default(), - config_mode: self.config_mode.clone(), + config_mode: self.config_mode_hash.clone(), }); } } @@ -284,7 +298,7 @@ where schema_id: Arc::clone(&self.schema.schema_id), metadata, plan_options, - config_mode: self.config_mode.clone(), + config_mode: self.config_mode_hash.clone(), }; if experimental_reuse_query_plans { @@ -490,7 +504,7 @@ where schema_id: Arc::clone(&self.schema.schema_id), metadata, plan_options, - config_mode: self.config_mode.clone(), + config_mode: self.config_mode_hash.clone(), }; let context = request.context.clone(); @@ -632,7 +646,7 @@ fn stats_report_key_hash(stats_report_key: &str) -> String { hex::encode(result) } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub(crate) struct CachingQueryKey { pub(crate) query: String, pub(crate) schema_id: Arc, @@ -640,12 +654,12 @@ pub(crate) struct CachingQueryKey { pub(crate) hash: Arc, pub(crate) metadata: CacheKeyMetadata, pub(crate) plan_options: PlanOptions, - pub(crate) config_mode: ConfigMode, + pub(crate) config_mode: Arc, } // Update this key every time the cache key or the query plan format has to change. // When changed it MUST BE CALLED OUT PROMINENTLY IN THE CHANGELOG. -const CACHE_KEY_VERSION: usize = 0; +const CACHE_KEY_VERSION: usize = 1; const FEDERATION_VERSION: &str = std::env!("FEDERATION_VERSION"); impl std::fmt::Display for CachingQueryKey { @@ -654,34 +668,23 @@ impl std::fmt::Display for CachingQueryKey { hasher.update(self.operation.as_deref().unwrap_or("-")); let operation = hex::encode(hasher.finalize()); - let mut hasher = Sha256::new(); - hasher.update(serde_json::to_vec(&self.metadata).expect("serialization should not fail")); - hasher - .update(serde_json::to_vec(&self.plan_options).expect("serialization should not fail")); - hasher - .update(serde_json::to_vec(&self.config_mode).expect("serialization should not fail")); - hasher.update(&*self.schema_id); + let mut hasher = StructHasher::new(); + "^metadata".hash(&mut hasher); + self.metadata.hash(&mut hasher); + "^plan_options".hash(&mut hasher); + self.plan_options.hash(&mut hasher); + "^config_mode".hash(&mut hasher); + self.config_mode.hash(&mut hasher); let metadata = hex::encode(hasher.finalize()); write!( f, - "plan:{}:{}:{}:{}:{}", + "plan:cache:{}:federation:{}:{}:opname:{}:metadata:{}", CACHE_KEY_VERSION, FEDERATION_VERSION, self.hash, operation, metadata, ) } } -impl Hash for CachingQueryKey { - fn hash(&self, state: &mut H) { - self.schema_id.hash(state); - self.hash.0.hash(state); - self.operation.hash(state); - self.metadata.hash(state); - self.plan_options.hash(state); - self.config_mode.hash(state); - } -} - #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub(crate) struct WarmUpCachingQueryKey { pub(crate) query: String, @@ -689,7 +692,33 @@ pub(crate) struct WarmUpCachingQueryKey { pub(crate) hash: Option>, pub(crate) metadata: CacheKeyMetadata, pub(crate) plan_options: PlanOptions, - pub(crate) config_mode: ConfigMode, + pub(crate) config_mode: Arc, +} + +struct StructHasher { + hasher: Sha256, +} + +impl StructHasher { + fn new() -> Self { + Self { + hasher: Sha256::new(), + } + } + fn finalize(self) -> Vec { + self.hasher.finalize().as_slice().into() + } +} + +impl Hasher for StructHasher { + fn finish(&self) -> u64 { + unreachable!() + } + + fn write(&mut self, bytes: &[u8]) { + self.hasher.update(&[0xFF][..]); + self.hasher.update(bytes); + } } impl ValueType for Result> { diff --git a/apollo-router/tests/integration/redis.rs b/apollo-router/tests/integration/redis.rs index 9e6af18826..ff42bf8d7e 100644 --- a/apollo-router/tests/integration/redis.rs +++ b/apollo-router/tests/integration/redis.rs @@ -51,7 +51,7 @@ async fn query_planner_cache() -> Result<(), BoxError> { } // If this test fails and the cache key format changed you'll need to update the key here. // Look at the top of the file for instructions on getting the new cache key. - let known_cache_key = "plan:0:v2.9.3:70f115ebba5991355c17f4f56ba25bb093c519c4db49a30f3b10de279a4e3fa4:3973e022e93220f9212c18d0d0c543ae7c309e46640da93a4a0314de999f5112:68e167191994b73c1892549ef57d0ec4cd76d518fad4dac5350846fe9af0b3f1"; + let known_cache_key = "plan:cache:1:federation:v2.9.3:70f115ebba5991355c17f4f56ba25bb093c519c4db49a30f3b10de279a4e3fa4:opname:3973e022e93220f9212c18d0d0c543ae7c309e46640da93a4a0314de999f5112:metadata:0ade8e18db172d9d51b36a2112513c15032d103100644df418a50596de3adfba"; let config = RedisConfig::from_url("redis://127.0.0.1:6379").unwrap(); let client = RedisClient::new(config, None, None, None); @@ -963,7 +963,7 @@ async fn connection_failure_blocks_startup() { async fn query_planner_redis_update_query_fragments() { test_redis_query_plan_config_update( include_str!("fixtures/query_planner_redis_config_update_query_fragments.router.yaml"), - "plan:0:v2.9.3:e15b4f5cd51b8cc728e3f5171611073455601e81196cd3cbafc5610d9769a370:3973e022e93220f9212c18d0d0c543ae7c309e46640da93a4a0314de999f5112:d239cf1d493e71f4bcb05e727c38e4cf55b32eb806791fa415bb6f6c8e5352e5", + "plan:cache:1:federation:v2.9.3:e15b4f5cd51b8cc728e3f5171611073455601e81196cd3cbafc5610d9769a370:opname:3973e022e93220f9212c18d0d0c543ae7c309e46640da93a4a0314de999f5112:metadata:1cfc840090ac76a98f8bd51442f41fd6ca4c8d918b3f8d87894170745acf0734", ) .await; } @@ -993,7 +993,7 @@ async fn query_planner_redis_update_defer() { // test just passes locally. test_redis_query_plan_config_update( include_str!("fixtures/query_planner_redis_config_update_defer.router.yaml"), - "plan:0:v2.9.3:e15b4f5cd51b8cc728e3f5171611073455601e81196cd3cbafc5610d9769a370:3973e022e93220f9212c18d0d0c543ae7c309e46640da93a4a0314de999f5112:752b870a0241594f54b7b593f16ab6cf6529eb5c9fe3d24e6bc4a618c24a5b81", + "plan:cache:1:federation:v2.9.3:e15b4f5cd51b8cc728e3f5171611073455601e81196cd3cbafc5610d9769a370:opname:3973e022e93220f9212c18d0d0c543ae7c309e46640da93a4a0314de999f5112:metadata:2f7fb939d2a8fc978e5a4e9d17998074fc30366dcc673236237a885819084fc0", ) .await; } @@ -1015,7 +1015,7 @@ async fn query_planner_redis_update_type_conditional_fetching() { include_str!( "fixtures/query_planner_redis_config_update_type_conditional_fetching.router.yaml" ), - "plan:0:v2.9.3:e15b4f5cd51b8cc728e3f5171611073455601e81196cd3cbafc5610d9769a370:3973e022e93220f9212c18d0d0c543ae7c309e46640da93a4a0314de999f5112:e2145b320a44bebbd687c714dcfd046c032e56fe394aedcf50d9ab539f4354ea", + "plan:cache:1:federation:v2.9.3:e15b4f5cd51b8cc728e3f5171611073455601e81196cd3cbafc5610d9769a370:opname:3973e022e93220f9212c18d0d0c543ae7c309e46640da93a4a0314de999f5112:metadata:0fd0a376f59f0565768ea5ad8eadfbbf60d64c593c807457a0776d2f39773a25", ) .await; } @@ -1037,7 +1037,7 @@ async fn query_planner_redis_update_reuse_query_fragments() { include_str!( "fixtures/query_planner_redis_config_update_reuse_query_fragments.router.yaml" ), - "plan:0:v2.9.3:e15b4f5cd51b8cc728e3f5171611073455601e81196cd3cbafc5610d9769a370:3973e022e93220f9212c18d0d0c543ae7c309e46640da93a4a0314de999f5112:8b6c1838a55cbc6327adb5507f103eed1d5b1071e9acb9c67e098c5b9ea2887e", + "plan:cache:1:federation:v2.9.3:e15b4f5cd51b8cc728e3f5171611073455601e81196cd3cbafc5610d9769a370:opname:3973e022e93220f9212c18d0d0c543ae7c309e46640da93a4a0314de999f5112:metadata:3f30f0e2d149d00c9370c8046e4dd5f23d6ceb6f05a6cf06d5eb021510564248", ) .await; } @@ -1062,7 +1062,7 @@ async fn test_redis_query_plan_config_update(updated_config: &str, new_cache_key router.clear_redis_cache().await; // If the tests above are failing, this is the key that needs to be changed first. - let starting_key = "plan:0:v2.9.3:e15b4f5cd51b8cc728e3f5171611073455601e81196cd3cbafc5610d9769a370:3973e022e93220f9212c18d0d0c543ae7c309e46640da93a4a0314de999f5112:41ae54204ebb1911412cf23e8f1d458cb08d6fabce16f255f7a497fd2b6fe213"; + let starting_key = "plan:cache:1:federation:v2.9.3:e15b4f5cd51b8cc728e3f5171611073455601e81196cd3cbafc5610d9769a370:opname:3973e022e93220f9212c18d0d0c543ae7c309e46640da93a4a0314de999f5112:metadata:0ade8e18db172d9d51b36a2112513c15032d103100644df418a50596de3adfba"; assert_ne!(starting_key, new_cache_key, "starting_key (cache key for the initial config) and new_cache_key (cache key with the updated config) should not be equal. This either means that the cache key is not being generated correctly, or that the test is not actually checking the updated key."); router.execute_default_query().await; From 5a868b6d2039c2be2f1d678bd03ab81f871205b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e?= Date: Wed, 6 Nov 2024 08:48:38 +0000 Subject: [PATCH 24/77] Limit the amount of GraphQL validation errors returned in the response (#6187) --- .changesets/fix_renee_limit_errors.md | 6 +++ apollo-router/src/error.rs | 14 ++++++- apollo-router/tests/integration/validation.rs | 38 +++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 .changesets/fix_renee_limit_errors.md diff --git a/.changesets/fix_renee_limit_errors.md b/.changesets/fix_renee_limit_errors.md new file mode 100644 index 0000000000..60a3404ccc --- /dev/null +++ b/.changesets/fix_renee_limit_errors.md @@ -0,0 +1,6 @@ +### Limit the amount of GraphQL validation errors returned in the response ([PR #6187](https://github.com/apollographql/router/pull/6187)) + +When an invalid query is submitted, the router now returns at most 100 GraphQL parsing and validation errors in the response. +This prevents generating a very large response for nonsense documents. + +By [@goto-bus-stop](https://github.com/goto-bus-stop) in https://github.com/apollographql/router/pull/6187 \ No newline at end of file diff --git a/apollo-router/src/error.rs b/apollo-router/src/error.rs index 80b075a915..b6281a58d6 100644 --- a/apollo-router/src/error.rs +++ b/apollo-router/src/error.rs @@ -26,6 +26,11 @@ use crate::json_ext::Value; use crate::spec::operation_limits::OperationLimits; use crate::spec::SpecError; +/// Return up to this many GraphQL parsing or validation errors. +/// +/// Any remaining errors get silently dropped. +const MAX_VALIDATION_ERRORS: usize = 100; + /// Error types for execution. /// /// Note that these are not actually returned to the client, but are instead converted to JSON for @@ -333,6 +338,7 @@ impl IntoGraphQLErrors for Vec { .extension_code("GRAPHQL_VALIDATION_FAILED") .build() }) + .take(MAX_VALIDATION_ERRORS) .collect()) } } @@ -605,6 +611,7 @@ impl IntoGraphQLErrors for ParseErrors { .extension_code("GRAPHQL_PARSING_FAILED") .build() }) + .take(MAX_VALIDATION_ERRORS) .collect()) } } @@ -635,6 +642,7 @@ impl ValidationErrors { .extension_code("GRAPHQL_VALIDATION_FAILED") .build() }) + .take(MAX_VALIDATION_ERRORS) .collect() } } @@ -647,7 +655,11 @@ impl IntoGraphQLErrors for ValidationErrors { impl From for ValidationErrors { fn from(errors: DiagnosticList) -> Self { Self { - errors: errors.iter().map(|e| e.unstable_to_json_compat()).collect(), + errors: errors + .iter() + .map(|e| e.unstable_to_json_compat()) + .take(MAX_VALIDATION_ERRORS) + .collect(), } } } diff --git a/apollo-router/tests/integration/validation.rs b/apollo-router/tests/integration/validation.rs index b5b0f6682d..fa5ed5cdcf 100644 --- a/apollo-router/tests/integration/validation.rs +++ b/apollo-router/tests/integration/validation.rs @@ -167,3 +167,41 @@ async fn test_validation_error() { } "###); } + +#[tokio::test] +async fn test_lots_of_validation_errors() { + let query = format!( + "{{ __typename {} }}", + "@a".repeat(4_000), // Stay under the token limit: "@a" is two tokens every time + ); + + let request = serde_json::json!({ "query": query }); + let request = apollo_router::services::router::Request::fake_builder() + .body(request.to_string()) + .method(hyper::Method::POST) + .header("content-type", "application/json") + .build() + .unwrap(); + let response = apollo_router::TestHarness::builder() + .schema(include_str!("../fixtures/supergraph.graphql")) + .build_router() + .await + .unwrap() + .oneshot(request) + .await + .unwrap() + .next_response() + .await + .unwrap() + .unwrap(); + + let v: serde_json::Value = serde_json::from_slice(&response).unwrap(); + let errors = v["errors"].as_array().unwrap(); + assert!(!errors.is_empty(), "should have errors"); + // Make sure we're actually testing the validation errors, and we're not hitting some other limit + assert_eq!( + errors.first().unwrap()["extensions"]["code"], + serde_json::Value::from("GRAPHQL_VALIDATION_FAILED") + ); + assert!(errors.len() <= 100, "should return limited error count"); +} From d18598fbc82ef95ded7d22cef1642170ad6b19df Mon Sep 17 00:00:00 2001 From: Nick Beach <136644049+nicksephora@users.noreply.github.com> Date: Wed, 6 Nov 2024 04:41:29 -0500 Subject: [PATCH 25/77] Helm: Update virtualservice.yaml to allow configurable host (#5545) Co-authored-by: Nick Beach Co-authored-by: Gary Pennington Co-authored-by: Jesse Rosenberger --- .changesets/helm_host_configuration.md | 6 ++++++ helm/chart/router/templates/virtualservice.yaml | 6 ++++++ helm/chart/router/values.yaml | 2 ++ 3 files changed, 14 insertions(+) create mode 100644 .changesets/helm_host_configuration.md diff --git a/.changesets/helm_host_configuration.md b/.changesets/helm_host_configuration.md new file mode 100644 index 0000000000..f64334803d --- /dev/null +++ b/.changesets/helm_host_configuration.md @@ -0,0 +1,6 @@ +### Allow for configuration of the host via the helm template for virtual service ([PR #5545](https://github.com/apollographql/router/pull/5795)) + +Using the virtual service template change allows the configuration of the host from a variable when doing helm deploy. +The default of any host causes issues for those that use different hosts for a single AKS cluster + +By [@nicksephora](https://github.com/nicksephora) in https://github.com/apollographql/router/pull/5545 diff --git a/helm/chart/router/templates/virtualservice.yaml b/helm/chart/router/templates/virtualservice.yaml index 1112750a3c..3d273583d7 100644 --- a/helm/chart/router/templates/virtualservice.yaml +++ b/helm/chart/router/templates/virtualservice.yaml @@ -20,7 +20,13 @@ metadata: {{- end }} spec: hosts: + { { if .Values.virtualservice.Hosts } } + { { - range .Values.virtualservice.Hosts } } + - { { . | quote } } + { { - end } } + { { - else } } - "*" + { { - end } } {{- if .Values.virtualservice.gatewayName }} gateways: - {{ .Values.virtualservice.gatewayName }} diff --git a/helm/chart/router/values.yaml b/helm/chart/router/values.yaml index 8540dd2f56..35f45618a7 100644 --- a/helm/chart/router/values.yaml +++ b/helm/chart/router/values.yaml @@ -167,6 +167,8 @@ virtualservice: # gatewayNames: [] # - "gateway-1" # - "gateway-2" + # Hosts: "" # configurable but will default to '*' + # - somehost.domain.com # http: # main: # # set enabled to true to add From 6516bb69d3eeb7e2510d5ec9d94c8319b5ccf74e Mon Sep 17 00:00:00 2001 From: Tyler Bloom Date: Wed, 6 Nov 2024 11:25:35 -0500 Subject: [PATCH 26/77] Upgrade Federation version in `apollo-federation` snapshot tests (#6237) --- .../query_plan/build_query_plan_support.rs | 4 ++-- ...sibling_typename_to_interface_object.graphql | 15 ++++++++++++--- .../adjacent_mutations_get_merged.graphql | 15 ++++++++++++--- .../allows_setting_down_to_1.graphql | 15 ++++++++++++--- ..._of_fragments_indirection_and_unions.graphql | 15 ++++++++++++--- ...e_root_when_a_more_direct_one_exists.graphql | 15 ++++++++++++--- .../avoids_unnecessary_fetches.graphql | 15 ++++++++++++--- .../basic_subscription_query_plan.graphql | 15 ++++++++++++--- ...ic_subscription_with_single_subgraph.graphql | 15 ++++++++++++--- .../can_be_set_to_an_arbitrary_number.graphql | 15 ++++++++++++--- ...only_partially_apply_in_entity_fetch.graphql | 15 ++++++++++++--- ...y_only_partially_apply_in_root_fetch.graphql | 15 ++++++++++++--- ...object_from_an_interface_object_type.graphql | 15 ++++++++++++--- ...se_a_key_on_an_interface_object_type.graphql | 15 ++++++++++++--- ...e_even_for_a_concrete_implementation.graphql | 15 ++++++++++++--- ..._from_multiple_subgraphs_in_parallel.graphql | 15 ++++++++++++--- .../condition_order_router799.graphql | 15 ++++++++++++--- ..._individually_optimal_branch_options.graphql | 15 ++++++++++++--- ..._there_is_too_many_plans_to_consider.graphql | 15 ++++++++++++--- .../supergraphs/defer_gets_stripped_out.graphql | 15 ++++++++++++--- ...est_can_request_typename_in_fragment.graphql | 15 ++++++++++++--- ..._test_defer_everything_within_entity.graphql | 15 ++++++++++++--- ...ltiple_fields_in_different_subgraphs.graphql | 15 ++++++++++++--- ...defer_on_enity_but_with_unuseful_key.graphql | 15 ++++++++++++--- ...fer_test_defer_on_everything_queried.graphql | 15 ++++++++++++--- ...on_multi_dependency_deferred_section.graphql | 15 ++++++++++++--- ...t_defer_on_mutation_in_same_subgraph.graphql | 15 ++++++++++++--- ...r_on_mutation_on_different_subgraphs.graphql | 15 ++++++++++++--- .../defer_test_defer_on_query_root_type.graphql | 15 ++++++++++++--- .../defer_test_defer_on_value_types.graphql | 15 ++++++++++++--- ...test_defer_only_the_key_of_an_entity.graphql | 15 ++++++++++++--- ..._defer_resuming_in_the_same_subgraph.graphql | 15 ++++++++++++--- ...er_with_condition_on_single_subgraph.graphql | 15 ++++++++++++--- ...est_defer_with_conditions_and_labels.graphql | 15 ++++++++++++--- ..._with_mutliple_conditions_and_labels.graphql | 15 ++++++++++++--- .../defer_test_direct_nesting_on_entity.graphql | 15 ++++++++++++--- ...er_test_direct_nesting_on_value_type.graphql | 15 ++++++++++++--- ..._not_merge_query_branches_with_defer.graphql | 15 ++++++++++++--- ..._into_same_field_regardless_of_defer.graphql | 15 ++++++++++++--- ...dles_simple_defer_with_defer_enabled.graphql | 15 ++++++++++++--- ...s_simple_defer_without_defer_enabled.graphql | 15 ++++++++++++--- ...ferent_definitions_between_subgraphs.graphql | 15 ++++++++++++--- ...non_nested_defer_plus_label_handling.graphql | 15 ++++++++++++--- .../defer_test_named_fragments_simple.graphql | 15 ++++++++++++--- .../defer_test_nested_defer_on_entities.graphql | 15 ++++++++++++--- ...test_non_router_based_defer_case_one.graphql | 15 ++++++++++++--- ...st_non_router_based_defer_case_three.graphql | 15 ++++++++++++--- ...test_non_router_based_defer_case_two.graphql | 15 ++++++++++++--- .../defer_test_normalizes_if_false.graphql | 15 ++++++++++++--- .../defer_test_normalizes_if_true.graphql | 15 ++++++++++++--- ...ides_are_ignored_for_deferred_fields.graphql | 15 ++++++++++++--- ...ents_of_deferred_fields_are_deferred.graphql | 15 ++++++++++++--- ...n_defer_includes_traversed_fragments.graphql | 15 ++++++++++++--- ...ome_complex_fetch_group_dependencies.graphql | 15 ++++++++++++--- ...when_interface_subtyping_is_involved.graphql | 15 ++++++++++++--- ...a_key_field_to_fetch_that_same_field.graphql | 15 ++++++++++++--- ...terface_object_directly_for_typename.graphql | 15 ++++++++++++--- ...specific_implementation_is_requested.graphql | 15 ++++++++++++--- ...ures_sanitization_applies_repeatedly.graphql | 15 ++++++++++++--- .../field_covariance_and_type_explosion.graphql | 15 ++++++++++++--- ...rwritten_when_directives_are_removed.graphql | 15 ++++++++++++--- ..._parent_type_and_directive_condition.graphql | 15 ++++++++++++--- ...erate_their_own_fragment_definitions.graphql | 15 ++++++++++++--- ...ndle_subgraph_with_hypen_in_the_name.graphql | 15 ++++++++++++--- .../handle_very_non_graph_subgraph_name.graphql | 15 ++++++++++++--- ...e_of_key_chains_in_parallel_requires.graphql | 15 ++++++++++++--- ...ments_with_interface_field_subtyping.graphql | 15 ++++++++++++--- ..._of_fragments_indirection_and_unions.graphql | 15 ++++++++++++--- ...ultiple_conditions_on_abstract_types.graphql | 15 ++++++++++++--- ...uires_involving_different_nestedness.graphql | 15 ++++++++++++--- ...non_intersecting_fragment_conditions.graphql | 15 ++++++++++++--- ...ng_value_types_under_interface_field.graphql | 15 ++++++++++++--- ...n_query_starts_with_interface_object.graphql | 15 ++++++++++++--- .../handles_requires_from_supergraph.graphql | 15 ++++++++++++--- ...peration_shareable_in_many_subgraphs.graphql | 15 ++++++++++++--- .../supergraphs/handles_simple_requires.graphql | 15 ++++++++++++--- .../handles_spread_unions_correctly.graphql | 15 ++++++++++++--- ...ommon_supertype_at_the_same_merge_at.graphql | 15 ++++++++++++--- .../interface_interface_interaction.graphql | 15 ++++++++++++--- ...eraction_but_no_need_to_type_explode.graphql | 15 ++++++++++++--- .../interface_union_interaction.graphql | 15 ++++++++++++--- ...eraction_but_no_need_to_type_explode.graphql | 15 ++++++++++++--- ...oviding_fields_for_only_some_subtype.graphql | 15 ++++++++++++--- .../it_avoid_fragments_usable_only_once.graphql | 15 ++++++++++++--- ...t_may_have_to_be_filtered_with_lists.graphql | 15 ++++++++++++--- ...t_can_require_at_inaccessible_fields.graphql | 17 +++++++++++++---- ...lessly_consider_options_for_typename.graphql | 15 ++++++++++++--- ...erride_unset_labels_on_entity_fields.graphql | 15 ++++++++++++--- ...unset_labels_on_nested_entity_fields.graphql | 15 ++++++++++++--- ...override_unset_labels_on_root_fields.graphql | 15 ++++++++++++--- ..._that_are_not_valid_for_the_subgraph.graphql | 15 ++++++++++++--- ...utes_mutation_operations_in_sequence.graphql | 15 ++++++++++++--- .../it_handes_diamond_shape_depedencies.graphql | 15 ++++++++++++--- ...uires_triggered_within_a_conditional.graphql | 15 ++++++++++++--- ..._at_requires_triggered_conditionally.graphql | 15 ++++++++++++--- ...re_multiple_conditional_are_involved.graphql | 15 ++++++++++++--- .../it_handles_complex_require_chain.graphql | 15 ++++++++++++--- ...here_some_subtyping_relation_differs.graphql | 15 ++++++++++++--- ...me_union_membership_relation_differs.graphql | 15 ++++++++++++--- ...es_fragments_with_one_non_leaf_field.graphql | 15 ++++++++++++--- ...es_interface_object_in_nested_entity.graphql | 15 ++++++++++++--- ...writes_when_cloning_dependency_graph.graphql | 15 ++++++++++++--- .../it_handles_longer_require_chain.graphql | 15 ++++++++++++--- ...tiple_requires_with_multiple_fetches.graphql | 15 ++++++++++++--- ...equires_within_the_same_entity_fetch.graphql | 15 ++++++++++++--- ...t_handles_nested_fragment_generation.graphql | 15 ++++++++++++--- ...rogressive_override_on_entity_fields.graphql | 15 ++++++++++++--- ...ive_override_on_nested_entity_fields.graphql | 15 ++++++++++++--- ..._progressive_override_on_root_fields.graphql | 15 ++++++++++++--- ...e_chain_not_ending_in_original_group.graphql | 15 ++++++++++++--- ...f_field_provided_by_interface_object.graphql | 15 ++++++++++++--- .../it_handles_simple_require_chain.graphql | 15 ++++++++++++--- ...alent_fragments_that_arent_identical.graphql | 15 ++++++++++++--- .../it_migrates_skip_include.graphql | 15 ++++++++++++--- ...ides_f1_to_s3_when_label_is_provided.graphql | 15 ++++++++++++--- ...errides_to_s2_when_label_is_provided.graphql | 15 ++++++++++++--- .../it_preservers_aliased_typename.graphql | 15 ++++++++++++--- ...s_directives_when_fragment_is_reused.graphql | 15 ++++++++++++--- ...es_directives_when_fragment_not_used.graphql | 15 ++++++++++++--- ...one_has_directives_and_is_eliminated.graphql | 15 ++++++++++++--- ...t_preserves_typename_with_directives.graphql | 15 ++++++++++++--- ...n_one_is_also_a_key_to_reach_another.graphql | 15 ++++++++++++--- ..._f1_in_s1_when_label_is_not_provided.graphql | 15 ++++++++++++--- ...ves_in_s1_when_label_is_not_provided.graphql | 15 ++++++++++++--- ...ects_generate_query_fragments_option.graphql | 15 ++++++++++++--- .../supergraphs/it_works_on_interfaces.graphql | 15 ++++++++++++--- .../supergraphs/it_works_on_unions.graphql | 15 ++++++++++++--- .../it_works_with_nested_fragments_1.graphql | 15 ++++++++++++--- ...y_the_nested_fragment_gets_preserved.graphql | 15 ++++++++++++--- .../it_works_with_nested_provides.graphql | 15 ++++++++++++--- ...es_only_reachable_by_the_at_provides.graphql | 15 ++++++++++++--- ...t_top_level_of_selection_of_requires.graphql | 15 ++++++++++++--- ...ultiple_applications_differing_order.graphql | 15 ++++++++++++--- ...iple_applications_differing_quantity.graphql | 15 ++++++++++++--- ...ives_multiple_applications_identical.graphql | 15 ++++++++++++--- ...and_include_directives_with_fragment.graphql | 15 ++++++++++++--- ..._include_directives_without_fragment.graphql | 15 ++++++++++++--- ...overflow_in_reduce_options_if_needed.graphql | 15 ++++++++++++--- ..._parent_type_and_directive_condition.graphql | 15 ++++++++++++--- ...adjacent_mutations_do_not_get_merged.graphql | 15 ++++++++++++--- ...y_uses_an_interface_object_if_it_can.graphql | 15 ++++++++++++--- .../pick_keys_that_minimize_fetches.graphql | 15 ++++++++++++--- ...ine_fragments_without_type_condition.graphql | 15 ++++++++++++--- ...r_option_reuse_query_fragments_false.graphql | 15 ++++++++++++--- ...er_option_reuse_query_fragments_true.graphql | 15 ++++++++++++--- .../supergraphs/same_as_js_router798.graphql | 15 ++++++++++++--- ...verwritten_after_removing_directives.graphql | 15 ++++++++++++--- ..._type_explosion_early_if_unnecessary.graphql | 15 ++++++++++++--- ..._the_directives_applied_to_the_query.graphql | 15 ++++++++++++--- ..._are_passed_down_to_subgraph_queries.graphql | 15 ++++++++++++--- ..._are_passed_down_to_subgraph_queries.graphql | 15 ++++++++++++--- ..._arguments_applied_on_queries_are_ok.graphql | 15 ++++++++++++--- ...branch_merging_with_typename_sibling.graphql | 15 ++++++++++++--- ...type_preserving_transitions_ordering.graphql | 15 ++++++++++++--- ...eate_cycle_in_fetch_dependency_graph.graphql | 15 ++++++++++++--- ...t_merging_fetches_reset_cached_costs.graphql | 15 ++++++++++++--- .../test_provides_edge_ordering.graphql | 15 ++++++++++++--- ...th_a_subcription_results_in_an_error.graphql | 15 ++++++++++++--- .../union_interface_interaction.graphql | 15 ++++++++++++--- ...eraction_but_no_need_to_type_explode.graphql | 15 ++++++++++++--- .../supergraphs/union_union_interaction.graphql | 15 ++++++++++++--- ...eraction_but_no_need_to_type_explode.graphql | 15 ++++++++++++--- ...y_include_is_stripped_from_fragments.graphql | 15 ++++++++++++--- .../supergraphs/works_when_unset.graphql | 15 ++++++++++++--- .../supergraphs/works_with_key_chains.graphql | 15 ++++++++++++--- 165 files changed, 1971 insertions(+), 495 deletions(-) diff --git a/apollo-federation/tests/query_plan/build_query_plan_support.rs b/apollo-federation/tests/query_plan/build_query_plan_support.rs index b73596590b..b7e02865c6 100644 --- a/apollo-federation/tests/query_plan/build_query_plan_support.rs +++ b/apollo-federation/tests/query_plan/build_query_plan_support.rs @@ -12,9 +12,9 @@ use apollo_federation::query_plan::TopLevelPlanNode; use apollo_federation::schema::ValidFederationSchema; use sha1::Digest; -const ROVER_FEDERATION_VERSION: &str = "2.7.4"; +const ROVER_FEDERATION_VERSION: &str = "2.9.0"; -const DEFAULT_LINK_DIRECTIVE: &str = r#"@link(url: "https://specs.apollo.dev/federation/v2.7", import: ["@key", "@requires", "@provides", "@external", "@tag", "@extends", "@shareable", "@inaccessible", "@override", "@composeDirective", "@interfaceObject"])"#; +const DEFAULT_LINK_DIRECTIVE: &str = r#"@link(url: "https://specs.apollo.dev/federation/v2.9", import: ["@key", "@requires", "@provides", "@external", "@tag", "@extends", "@shareable", "@inaccessible", "@override", "@composeDirective", "@interfaceObject", "@context", "@fromContext", "@cost", "@listSize"])"#; /// Runs composition on the given subgraph schemas and return `(api_schema, query_planner)` /// diff --git a/apollo-federation/tests/query_plan/supergraphs/add_back_sibling_typename_to_interface_object.graphql b/apollo-federation/tests/query_plan/supergraphs/add_back_sibling_typename_to_interface_object.graphql index 08d3c44ea2..fcf86133d8 100644 --- a/apollo-federation/tests/query_plan/supergraphs/add_back_sibling_typename_to_interface_object.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/add_back_sibling_typename_to_interface_object.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 9c69e32dbbd50fb46ea218c3581b08f4f084b9b9 +# Composed from subgraphs with hash: 36b8aac0fd3b63ab6a2e4d913ce66381d9c97df2 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -46,10 +46,19 @@ interface Item name: String! @join__field(graph: SUBGRAPH1) } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/adjacent_mutations_get_merged.graphql b/apollo-federation/tests/query_plan/supergraphs/adjacent_mutations_get_merged.graphql index ae84cc8ed8..6764677f0c 100644 --- a/apollo-federation/tests/query_plan/supergraphs/adjacent_mutations_get_merged.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/adjacent_mutations_get_merged.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 54adb76945715a2ce0e068d2635d71ca4166b289 +# Composed from subgraphs with hash: e7bdd5a089836a642476b6cb289e21dfe867b4ab schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query mutation: Mutation @@ -11,7 +11,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -32,10 +32,19 @@ type Foo baz: Int @join__field(graph: SUBGRAPHB) } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPHA @join__graph(name: "SubgraphA", url: "none") SUBGRAPHB @join__graph(name: "SubgraphB", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/allows_setting_down_to_1.graphql b/apollo-federation/tests/query_plan/supergraphs/allows_setting_down_to_1.graphql index 42f3b4b125..a1f388ed61 100644 --- a/apollo-federation/tests/query_plan/supergraphs/allows_setting_down_to_1.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/allows_setting_down_to_1.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 91d4d0661d413b60ae2ed463c074c4180d7b849e +# Composed from subgraphs with hash: a9236eee956ed7fc219b2212696478159ced7eea schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/another_mix_of_fragments_indirection_and_unions.graphql b/apollo-federation/tests/query_plan/supergraphs/another_mix_of_fragments_indirection_and_unions.graphql index 9b6bb51265..d92ae75216 100644 --- a/apollo-federation/tests/query_plan/supergraphs/another_mix_of_fragments_indirection_and_unions.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/another_mix_of_fragments_indirection_and_unions.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: b0bcf31c6c8c64e53e4286dbf397738e41ecbda7 +# Composed from subgraphs with hash: 7e1730cfe16f02de891d008c1310a8355a4b90ab schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -29,10 +29,19 @@ interface I id2: ID! } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/avoid_considering_indirect_paths_from_the_root_when_a_more_direct_one_exists.graphql b/apollo-federation/tests/query_plan/supergraphs/avoid_considering_indirect_paths_from_the_root_when_a_more_direct_one_exists.graphql index b5d2335e2c..7adf9f6c3b 100644 --- a/apollo-federation/tests/query_plan/supergraphs/avoid_considering_indirect_paths_from_the_root_when_a_more_direct_one_exists.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/avoid_considering_indirect_paths_from_the_root_when_a_more_direct_one_exists.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 9df3e1f539626e2d33ad1aeab8fa51e27fd1f441 +# Composed from subgraphs with hash: 5fba714136085371e4c18ce29483c028c1bcb461 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/avoids_unnecessary_fetches.graphql b/apollo-federation/tests/query_plan/supergraphs/avoids_unnecessary_fetches.graphql index 7ea5c3595d..d9a20ac109 100644 --- a/apollo-federation/tests/query_plan/supergraphs/avoids_unnecessary_fetches.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/avoids_unnecessary_fetches.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 8ba19e06c01ab40b92eda93ac77de08c57856299 +# Composed from subgraphs with hash: f7159b1ede74b4019a8e8f7dfb58369fb4890797 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -32,10 +32,19 @@ type A idA1: ID! @join__field(graph: SUBGRAPH3) @join__field(graph: SUBGRAPH4) } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/basic_subscription_query_plan.graphql b/apollo-federation/tests/query_plan/supergraphs/basic_subscription_query_plan.graphql index 8b559e6727..075d5bd978 100644 --- a/apollo-federation/tests/query_plan/supergraphs/basic_subscription_query_plan.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/basic_subscription_query_plan.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: f7613316e8b925d2e1fb7f78b351920adfa4a595 +# Composed from subgraphs with hash: c8a41e00d374bc7c77184e0ffa9fae7d65868f14 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query subscription: Subscription @@ -11,7 +11,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -23,10 +23,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPHA @join__graph(name: "SubgraphA", url: "none") SUBGRAPHB @join__graph(name: "SubgraphB", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/basic_subscription_with_single_subgraph.graphql b/apollo-federation/tests/query_plan/supergraphs/basic_subscription_with_single_subgraph.graphql index e917252972..221faf8ee5 100644 --- a/apollo-federation/tests/query_plan/supergraphs/basic_subscription_with_single_subgraph.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/basic_subscription_with_single_subgraph.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 409fcb3d17fb926642cf9483b5c1db292c219eb1 +# Composed from subgraphs with hash: 8588d7e3fac21b6a30d96678baaf1b49eda0fc99 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query subscription: Subscription @@ -11,7 +11,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -23,10 +23,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPHA @join__graph(name: "SubgraphA", url: "none") SUBGRAPHB @join__graph(name: "SubgraphB", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/can_be_set_to_an_arbitrary_number.graphql b/apollo-federation/tests/query_plan/supergraphs/can_be_set_to_an_arbitrary_number.graphql index 42f3b4b125..a1f388ed61 100644 --- a/apollo-federation/tests/query_plan/supergraphs/can_be_set_to_an_arbitrary_number.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/can_be_set_to_an_arbitrary_number.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 91d4d0661d413b60ae2ed463c074c4180d7b849e +# Composed from subgraphs with hash: a9236eee956ed7fc219b2212696478159ced7eea schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/can_reuse_fragments_in_subgraph_where_they_only_partially_apply_in_entity_fetch.graphql b/apollo-federation/tests/query_plan/supergraphs/can_reuse_fragments_in_subgraph_where_they_only_partially_apply_in_entity_fetch.graphql index 077541aced..fc5780d254 100644 --- a/apollo-federation/tests/query_plan/supergraphs/can_reuse_fragments_in_subgraph_where_they_only_partially_apply_in_entity_fetch.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/can_reuse_fragments_in_subgraph_where_they_only_partially_apply_in_entity_fetch.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 24f37faeded16eb10b0ffc6c3c2a0e936f406801 +# Composed from subgraphs with hash: f8053ffafe0a672063ce2538526e3eccba5c20dc schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/can_reuse_fragments_in_subgraph_where_they_only_partially_apply_in_root_fetch.graphql b/apollo-federation/tests/query_plan/supergraphs/can_reuse_fragments_in_subgraph_where_they_only_partially_apply_in_root_fetch.graphql index 4d21c8ec70..a90f6900c4 100644 --- a/apollo-federation/tests/query_plan/supergraphs/can_reuse_fragments_in_subgraph_where_they_only_partially_apply_in_root_fetch.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/can_reuse_fragments_in_subgraph_where_they_only_partially_apply_in_root_fetch.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: d4c3168300df54a934d76deb9884e98ba647a676 +# Composed from subgraphs with hash: fe011bd445bfbe40ce53510ba9799480136421c3 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/can_use_a_key_on_an_interface_object_from_an_interface_object_type.graphql b/apollo-federation/tests/query_plan/supergraphs/can_use_a_key_on_an_interface_object_from_an_interface_object_type.graphql index 97189f9365..1226b3f64e 100644 --- a/apollo-federation/tests/query_plan/supergraphs/can_use_a_key_on_an_interface_object_from_an_interface_object_type.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/can_use_a_key_on_an_interface_object_from_an_interface_object_type.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: da551e74f6885542cefc64ed31d2b00579dce2cd +# Composed from subgraphs with hash: 2d8573a4a560444417df271ed0a39b18c366dbc0 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -51,10 +51,19 @@ interface I y: Int @join__field(graph: S2) } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "S1", url: "none") S2 @join__graph(name: "S2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/can_use_a_key_on_an_interface_object_type.graphql b/apollo-federation/tests/query_plan/supergraphs/can_use_a_key_on_an_interface_object_type.graphql index 97189f9365..1226b3f64e 100644 --- a/apollo-federation/tests/query_plan/supergraphs/can_use_a_key_on_an_interface_object_type.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/can_use_a_key_on_an_interface_object_type.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: da551e74f6885542cefc64ed31d2b00579dce2cd +# Composed from subgraphs with hash: 2d8573a4a560444417df271ed0a39b18c366dbc0 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -51,10 +51,19 @@ interface I y: Int @join__field(graph: S2) } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "S1", url: "none") S2 @join__graph(name: "S2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/can_use_a_key_on_an_interface_object_type_even_for_a_concrete_implementation.graphql b/apollo-federation/tests/query_plan/supergraphs/can_use_a_key_on_an_interface_object_type_even_for_a_concrete_implementation.graphql index 97189f9365..1226b3f64e 100644 --- a/apollo-federation/tests/query_plan/supergraphs/can_use_a_key_on_an_interface_object_type_even_for_a_concrete_implementation.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/can_use_a_key_on_an_interface_object_type_even_for_a_concrete_implementation.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: da551e74f6885542cefc64ed31d2b00579dce2cd +# Composed from subgraphs with hash: 2d8573a4a560444417df271ed0a39b18c366dbc0 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -51,10 +51,19 @@ interface I y: Int @join__field(graph: S2) } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "S1", url: "none") S2 @join__graph(name: "S2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/can_use_same_root_operation_from_multiple_subgraphs_in_parallel.graphql b/apollo-federation/tests/query_plan/supergraphs/can_use_same_root_operation_from_multiple_subgraphs_in_parallel.graphql index 843563aa3f..d7d10a5dcc 100644 --- a/apollo-federation/tests/query_plan/supergraphs/can_use_same_root_operation_from_multiple_subgraphs_in_parallel.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/can_use_same_root_operation_from_multiple_subgraphs_in_parallel.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 34751a1a79473dcec3aad139f107e5b73a855e0d +# Composed from subgraphs with hash: 40f5afa1d1f5960b7758506956c002b7f3bb3f96 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/condition_order_router799.graphql b/apollo-federation/tests/query_plan/supergraphs/condition_order_router799.graphql index 69ef1b485a..91f7154b37 100644 --- a/apollo-federation/tests/query_plan/supergraphs/condition_order_router799.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/condition_order_router799.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 3ebe0e8c55ad21763879da6341617f14953e80d7 +# Composed from subgraphs with hash: 315fa785fb98377a538827892fc251e5278411df schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query mutation: Mutation @@ -11,7 +11,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -23,10 +23,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { BOOKS @join__graph(name: "books", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/correctly_generate_plan_built_from_some_non_individually_optimal_branch_options.graphql b/apollo-federation/tests/query_plan/supergraphs/correctly_generate_plan_built_from_some_non_individually_optimal_branch_options.graphql index 56e9fef51e..86f3657ed3 100644 --- a/apollo-federation/tests/query_plan/supergraphs/correctly_generate_plan_built_from_some_non_individually_optimal_branch_options.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/correctly_generate_plan_built_from_some_non_individually_optimal_branch_options.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 6ca9a3e7d089605b227c291630c3f089dde1f38d +# Composed from subgraphs with hash: 2a54a92bba655ef6aba52073886d8834898e3f9e schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/correctly_handle_case_where_there_is_too_many_plans_to_consider.graphql b/apollo-federation/tests/query_plan/supergraphs/correctly_handle_case_where_there_is_too_many_plans_to_consider.graphql index 80f221ab6f..7ca7c24f4b 100644 --- a/apollo-federation/tests/query_plan/supergraphs/correctly_handle_case_where_there_is_too_many_plans_to_consider.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/correctly_handle_case_where_there_is_too_many_plans_to_consider.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 8a8e74cff42f95e71955aa96d62ef9f9589739d5 +# Composed from subgraphs with hash: 50c5a3e3aada2517a4ded58b107fb6c1f368a9e2 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "S1", url: "none") S2 @join__graph(name: "S2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_gets_stripped_out.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_gets_stripped_out.graphql index ec6c89f59b..e77c1b39e8 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_gets_stripped_out.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_gets_stripped_out.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 3e20191edc9bb3ef7d687ce811c347718e6e4100 +# Composed from subgraphs with hash: 71f5545b94f1467afa42deb9d802e13d0d6af30f schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_can_request_typename_in_fragment.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_can_request_typename_in_fragment.graphql index 20cd0d93cd..c7177ab189 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_can_request_typename_in_fragment.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_can_request_typename_in_fragment.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: e2543fc649c80a566b573ebfad36fc0f7458a3a4 +# Composed from subgraphs with hash: 4650b586dd619bfef02a467d67602c065d4b0ed2 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_everything_within_entity.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_everything_within_entity.graphql index 3fb06aff10..b2bdd66659 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_everything_within_entity.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_everything_within_entity.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 428d657ed6389527be73c6ad949cd2fc4da01b20 +# Composed from subgraphs with hash: 22e24356e106228bb20c17c7dabbf476fde27e22 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_multiple_fields_in_different_subgraphs.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_multiple_fields_in_different_subgraphs.graphql index a03862f610..3f2ce69345 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_multiple_fields_in_different_subgraphs.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_multiple_fields_in_different_subgraphs.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 6de814e8aeb455e136ac8627284d67ef4806de57 +# Composed from subgraphs with hash: 15876cef8879238c8dad83fa7976f2925553a806 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_enity_but_with_unuseful_key.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_enity_but_with_unuseful_key.graphql index 3467b225d6..7e45fb8255 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_enity_but_with_unuseful_key.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_enity_but_with_unuseful_key.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: e9d8806fbdfd92a23a7dd2af1e343ff3b6de4a7c +# Composed from subgraphs with hash: a8cdce83720ad36769df084cc55e8b418099bca5 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_everything_queried.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_everything_queried.graphql index 3fb06aff10..b2bdd66659 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_everything_queried.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_everything_queried.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 428d657ed6389527be73c6ad949cd2fc4da01b20 +# Composed from subgraphs with hash: 22e24356e106228bb20c17c7dabbf476fde27e22 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_multi_dependency_deferred_section.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_multi_dependency_deferred_section.graphql index 987e5b30e3..eb886f2ec9 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_multi_dependency_deferred_section.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_multi_dependency_deferred_section.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: cb3bc5e47277ef2c4a364fa62067cfc2426974ec +# Composed from subgraphs with hash: cf4534a5c50af23995f1e5aa82b79e9a858b92bf schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_mutation_in_same_subgraph.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_mutation_in_same_subgraph.graphql index e2f0483965..d3740197e4 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_mutation_in_same_subgraph.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_mutation_in_same_subgraph.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: e33e3ea89ff4340ccd53321764ac7f1a2684eb3f +# Composed from subgraphs with hash: 078a72747c6fbfb51e60cd9f7959b3b158495800 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query mutation: Mutation @@ -11,7 +11,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -23,10 +23,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_mutation_on_different_subgraphs.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_mutation_on_different_subgraphs.graphql index b2e03a0693..950283032c 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_mutation_on_different_subgraphs.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_mutation_on_different_subgraphs.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 557c634741b7e9f2f4288edb43724e47f1983d19 +# Composed from subgraphs with hash: d44e187a9a459bd70767ee503e7a1dc4c783d0bf schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query mutation: Mutation @@ -11,7 +11,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -23,10 +23,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_query_root_type.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_query_root_type.graphql index 74e78631de..415d482319 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_query_root_type.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_query_root_type.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 0a1dc62b0c2282030c10f0e0f777f635d6abd3ba +# Composed from subgraphs with hash: 02b05d7c673780361314e10cefea62f6d79d8e3b schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -30,10 +30,19 @@ type A next: Query } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_value_types.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_value_types.graphql index 6167ec55b4..45a3a334ff 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_value_types.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_on_value_types.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 01170823ab6c07812976d0983a101d49a319af5c +# Composed from subgraphs with hash: 5cea36a97a40394811ab9ccf97df46c40dcd8ebc schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_only_the_key_of_an_entity.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_only_the_key_of_an_entity.graphql index f41a6d9198..d4a1f50901 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_only_the_key_of_an_entity.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_only_the_key_of_an_entity.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 176bb27a622184464209652e70141da92aeef370 +# Composed from subgraphs with hash: 6b693215fbaac31a45aba14a606333aad808ef8e schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_resuming_in_the_same_subgraph.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_resuming_in_the_same_subgraph.graphql index 33e9d9c2d9..ba3655a4f0 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_resuming_in_the_same_subgraph.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_resuming_in_the_same_subgraph.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 0e99f2e41acb0f707744e78845a55271589146e6 +# Composed from subgraphs with hash: ead6b9a76f52b7caba51acba21fdd37fa52e369a schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_with_condition_on_single_subgraph.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_with_condition_on_single_subgraph.graphql index b185de90ba..56685d5da5 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_with_condition_on_single_subgraph.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_with_condition_on_single_subgraph.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 59e305d633b6e337422f6431c32cc58defa07302 +# Composed from subgraphs with hash: 6da68bcd4562ba2b8aea44307e29b2b409da8920 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_with_conditions_and_labels.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_with_conditions_and_labels.graphql index 20cd0d93cd..c7177ab189 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_with_conditions_and_labels.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_with_conditions_and_labels.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: e2543fc649c80a566b573ebfad36fc0f7458a3a4 +# Composed from subgraphs with hash: 4650b586dd619bfef02a467d67602c065d4b0ed2 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_with_mutliple_conditions_and_labels.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_with_mutliple_conditions_and_labels.graphql index 1b7e7bdb70..81e36df9a3 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_with_mutliple_conditions_and_labels.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_defer_with_mutliple_conditions_and_labels.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 2135cbed03439b8658c0113e4663849c991e244b +# Composed from subgraphs with hash: 21f2df1c19b833341b4f9643d34ea0b9cef55ab4 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_direct_nesting_on_entity.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_direct_nesting_on_entity.graphql index 004ed2cf9c..2148644c49 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_direct_nesting_on_entity.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_direct_nesting_on_entity.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 355f15f0f2699fd21731b0403286c513357860d3 +# Composed from subgraphs with hash: 929471dddc80c1a51b87f346eb2f416084d542eb schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_direct_nesting_on_value_type.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_direct_nesting_on_value_type.graphql index 992f860b3a..b73e20a4e4 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_direct_nesting_on_value_type.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_direct_nesting_on_value_type.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: f507628640adf8891453e78dbd4280a132706b11 +# Composed from subgraphs with hash: e99d2671927f9c6a1ee42f44d3c386ade3094009 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_do_not_merge_query_branches_with_defer.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_do_not_merge_query_branches_with_defer.graphql index 6beeae8fd0..6e7383b221 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_do_not_merge_query_branches_with_defer.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_do_not_merge_query_branches_with_defer.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 6af2331e8c3844fbee6c3888b80b44f51cd5bd3d +# Composed from subgraphs with hash: e3be845f74566fd4e434d5d8bf76f6bc7ea62166 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_fragments_expand_into_same_field_regardless_of_defer.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_fragments_expand_into_same_field_regardless_of_defer.graphql index c952a4d998..af0171dca5 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_fragments_expand_into_same_field_regardless_of_defer.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_fragments_expand_into_same_field_regardless_of_defer.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 5382aae137e16d1dfb9955e2a5118b49c75320ea +# Composed from subgraphs with hash: 98071a61d2822a625067b9d1f84c36ca368801d9 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_handles_simple_defer_with_defer_enabled.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_handles_simple_defer_with_defer_enabled.graphql index 385d1b4566..a8a5a9ecfd 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_handles_simple_defer_with_defer_enabled.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_handles_simple_defer_with_defer_enabled.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: f7c59d88291d4be94f4c484dc849118a08361e69 +# Composed from subgraphs with hash: 6f4f2bbb16236373f2eba847b503d19498249c01 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_handles_simple_defer_without_defer_enabled.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_handles_simple_defer_without_defer_enabled.graphql index 385d1b4566..a8a5a9ecfd 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_handles_simple_defer_without_defer_enabled.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_handles_simple_defer_without_defer_enabled.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: f7c59d88291d4be94f4c484dc849118a08361e69 +# Composed from subgraphs with hash: 6f4f2bbb16236373f2eba847b503d19498249c01 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_interface_has_different_definitions_between_subgraphs.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_interface_has_different_definitions_between_subgraphs.graphql index 3fc0c2ca0c..b51cecf205 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_interface_has_different_definitions_between_subgraphs.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_interface_has_different_definitions_between_subgraphs.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: d280d3aae78ad7080c8df8b5a8982d70a4000a78 +# Composed from subgraphs with hash: f2201cf706257dc01dcf09fb0ae827af3b9fa88e schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -31,10 +31,19 @@ interface I b: Int @join__field(graph: SUBGRAPH2) } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_multiple_non_nested_defer_plus_label_handling.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_multiple_non_nested_defer_plus_label_handling.graphql index e35ec30241..63b929b522 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_multiple_non_nested_defer_plus_label_handling.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_multiple_non_nested_defer_plus_label_handling.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 09643fc5e0d3abcab8a0f25c0c1e4e16da4169a4 +# Composed from subgraphs with hash: 4c287523c033f1b01e358623f51eb8b9ac3dcd85 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_named_fragments_simple.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_named_fragments_simple.graphql index e8552cbd81..bbb73f12e9 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_named_fragments_simple.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_named_fragments_simple.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 395eb0d8e844d7a54e82eec772f007fafcc37a8e +# Composed from subgraphs with hash: 5f3018ae7e7b98a497ce4fbe8dcd5180c065da06 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_nested_defer_on_entities.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_nested_defer_on_entities.graphql index 10c0f0e1cd..88352b373a 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_nested_defer_on_entities.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_nested_defer_on_entities.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 1ddb9374f772bf962933f20e08543315e8df2b01 +# Composed from subgraphs with hash: b5d17f8a99a3b6c92c1c3f78456e46fadc515cf5 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_non_router_based_defer_case_one.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_non_router_based_defer_case_one.graphql index 6f00c992a6..2e67927893 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_non_router_based_defer_case_one.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_non_router_based_defer_case_one.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 3bee990c996344aa1eb3a7211e3f497fcbe5e1a6 +# Composed from subgraphs with hash: 3c1a8e679e219bea6bc85b846327ff42bdfac701 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_non_router_based_defer_case_three.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_non_router_based_defer_case_three.graphql index b5cdcdd682..0a77a773ea 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_non_router_based_defer_case_three.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_non_router_based_defer_case_three.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: c6019a1bd80338506615bb1b60a44fc384586a47 +# Composed from subgraphs with hash: 29206c46cff52b5aadce1935a0f3175d5aacb8dd schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_non_router_based_defer_case_two.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_non_router_based_defer_case_two.graphql index a132722729..095d8d42b7 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_non_router_based_defer_case_two.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_non_router_based_defer_case_two.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: fc9fa92848d4ab0e200dcfd09762db2e4281efae +# Composed from subgraphs with hash: a985245292473d8c3e90fc33a9c69754285492cc schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_normalizes_if_false.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_normalizes_if_false.graphql index 385d1b4566..a8a5a9ecfd 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_normalizes_if_false.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_normalizes_if_false.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: f7c59d88291d4be94f4c484dc849118a08361e69 +# Composed from subgraphs with hash: 6f4f2bbb16236373f2eba847b503d19498249c01 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_normalizes_if_true.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_normalizes_if_true.graphql index 385d1b4566..a8a5a9ecfd 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_normalizes_if_true.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_normalizes_if_true.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: f7c59d88291d4be94f4c484dc849118a08361e69 +# Composed from subgraphs with hash: 6f4f2bbb16236373f2eba847b503d19498249c01 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_provides_are_ignored_for_deferred_fields.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_provides_are_ignored_for_deferred_fields.graphql index a18f8f7682..7e68977699 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_provides_are_ignored_for_deferred_fields.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_provides_are_ignored_for_deferred_fields.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 39be4a27050623ad7a03d8ae9fed684d1e0f3088 +# Composed from subgraphs with hash: d4bf20edb94edf0cfe2d81956633e26905b36c4e schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_requirements_of_deferred_fields_are_deferred.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_requirements_of_deferred_fields_are_deferred.graphql index 0e2903ca92..6cfc2792cc 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_requirements_of_deferred_fields_are_deferred.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_requirements_of_deferred_fields_are_deferred.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: b3f138a89fd35476e9e36002ae4c8c1ab51c4530 +# Composed from subgraphs with hash: b8bd40a365081d5870913002ff2d4bf0dba0af58 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/defer_test_the_path_in_defer_includes_traversed_fragments.graphql b/apollo-federation/tests/query_plan/supergraphs/defer_test_the_path_in_defer_includes_traversed_fragments.graphql index 82c2cfae78..0075f29bc4 100644 --- a/apollo-federation/tests/query_plan/supergraphs/defer_test_the_path_in_defer_includes_traversed_fragments.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/defer_test_the_path_in_defer_includes_traversed_fragments.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: eea1ddd3f3e944aaeb5f39f8f9018fd32bcdaaf6 +# Composed from subgraphs with hash: 195dbb671585fe1c25717d53d9d35239abd2e09f schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -36,10 +36,19 @@ interface I x: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/does_not_error_on_some_complex_fetch_group_dependencies.graphql b/apollo-federation/tests/query_plan/supergraphs/does_not_error_on_some_complex_fetch_group_dependencies.graphql index 950263d878..3c79268f77 100644 --- a/apollo-federation/tests/query_plan/supergraphs/does_not_error_on_some_complex_fetch_group_dependencies.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/does_not_error_on_some_complex_fetch_group_dependencies.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 604dead6fd018b16380a1abf51ba199acbdb82f2 +# Composed from subgraphs with hash: c32793dd157c67a6637ceabda719536fc3c703d3 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/does_not_error_out_handling_fragments_when_interface_subtyping_is_involved.graphql b/apollo-federation/tests/query_plan/supergraphs/does_not_error_out_handling_fragments_when_interface_subtyping_is_involved.graphql index 5137fdf735..5e7fdd2848 100644 --- a/apollo-federation/tests/query_plan/supergraphs/does_not_error_out_handling_fragments_when_interface_subtyping_is_involved.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/does_not_error_out_handling_fragments_when_interface_subtyping_is_involved.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 85a2b796ad6f1553ddbc0bf5f4722e602f475090 +# Composed from subgraphs with hash: 7a5c84b7ae6162a788aa569091fcd5a8fe8c4771 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -49,10 +49,19 @@ interface IB v1: Int! } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/does_not_evaluate_plans_relying_on_a_key_field_to_fetch_that_same_field.graphql b/apollo-federation/tests/query_plan/supergraphs/does_not_evaluate_plans_relying_on_a_key_field_to_fetch_that_same_field.graphql index 674a08c9f2..0aebde659c 100644 --- a/apollo-federation/tests/query_plan/supergraphs/does_not_evaluate_plans_relying_on_a_key_field_to_fetch_that_same_field.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/does_not_evaluate_plans_relying_on_a_key_field_to_fetch_that_same_field.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: e4cc087ad60a261439df7beadccbe9b4a31eaa8d +# Composed from subgraphs with hash: 408f5bf6c20bc49fa52320c529af66fbb36287dd schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/does_not_rely_on_an_interface_object_directly_for_typename.graphql b/apollo-federation/tests/query_plan/supergraphs/does_not_rely_on_an_interface_object_directly_for_typename.graphql index 97189f9365..1226b3f64e 100644 --- a/apollo-federation/tests/query_plan/supergraphs/does_not_rely_on_an_interface_object_directly_for_typename.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/does_not_rely_on_an_interface_object_directly_for_typename.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: da551e74f6885542cefc64ed31d2b00579dce2cd +# Composed from subgraphs with hash: 2d8573a4a560444417df271ed0a39b18c366dbc0 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -51,10 +51,19 @@ interface I y: Int @join__field(graph: S2) } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "S1", url: "none") S2 @join__graph(name: "S2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/does_not_rely_on_an_interface_object_directly_if_a_specific_implementation_is_requested.graphql b/apollo-federation/tests/query_plan/supergraphs/does_not_rely_on_an_interface_object_directly_if_a_specific_implementation_is_requested.graphql index 97189f9365..1226b3f64e 100644 --- a/apollo-federation/tests/query_plan/supergraphs/does_not_rely_on_an_interface_object_directly_if_a_specific_implementation_is_requested.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/does_not_rely_on_an_interface_object_directly_if_a_specific_implementation_is_requested.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: da551e74f6885542cefc64ed31d2b00579dce2cd +# Composed from subgraphs with hash: 2d8573a4a560444417df271ed0a39b18c366dbc0 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -51,10 +51,19 @@ interface I y: Int @join__field(graph: S2) } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "S1", url: "none") S2 @join__graph(name: "S2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/ensures_sanitization_applies_repeatedly.graphql b/apollo-federation/tests/query_plan/supergraphs/ensures_sanitization_applies_repeatedly.graphql index f62dcb21b5..35a2de8da7 100644 --- a/apollo-federation/tests/query_plan/supergraphs/ensures_sanitization_applies_repeatedly.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/ensures_sanitization_applies_repeatedly.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 5a37dc86c56cab4caab8bb5d9606eb4c7df0d804 +# Composed from subgraphs with hash: bb70b30ff3918c2d33483331b733c724cbd8631d schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "S1", url: "none") A_NA_ME_WITH_PLEN_TY_REPLACE_MENTS @join__graph(name: "a-na&me-with-plen&ty-replace*ments", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/field_covariance_and_type_explosion.graphql b/apollo-federation/tests/query_plan/supergraphs/field_covariance_and_type_explosion.graphql index 923bde8335..693e39ab51 100644 --- a/apollo-federation/tests/query_plan/supergraphs/field_covariance_and_type_explosion.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/field_covariance_and_type_explosion.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 2254345d779de0a2850b6c7a5db722f1989a774c +# Composed from subgraphs with hash: 184d4f82c7a51478107e30ce8aee3d1862c804c2 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -28,10 +28,19 @@ interface Interface field: Interface } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/fields_are_not_overwritten_when_directives_are_removed.graphql b/apollo-federation/tests/query_plan/supergraphs/fields_are_not_overwritten_when_directives_are_removed.graphql index 1b369c434a..2b0526beb0 100644 --- a/apollo-federation/tests/query_plan/supergraphs/fields_are_not_overwritten_when_directives_are_removed.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/fields_are_not_overwritten_when_directives_are_removed.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 654c7bcba86c6f5845a7cb520710cfa37b678e3d +# Composed from subgraphs with hash: 8afd32067575aaae505bac05752941b0314b3cf0 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -35,10 +35,19 @@ type Foo bar: Bar } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPHSKIP @join__graph(name: "SubgraphSkip", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/fragment_with_intersecting_parent_type_and_directive_condition.graphql b/apollo-federation/tests/query_plan/supergraphs/fragment_with_intersecting_parent_type_and_directive_condition.graphql index 1e2a373495..6c5379daff 100644 --- a/apollo-federation/tests/query_plan/supergraphs/fragment_with_intersecting_parent_type_and_directive_condition.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/fragment_with_intersecting_parent_type_and_directive_condition.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: e2393609250b71261acc4089006bc8a14627d488 +# Composed from subgraphs with hash: 60b6f32feef51579a2b534cc06e803a7fd2aa5d8 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -37,10 +37,19 @@ interface I2 title: String } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { A @join__graph(name: "A", url: "none") B @join__graph(name: "B", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/fragments_that_share_a_hash_but_are_not_identical_generate_their_own_fragment_definitions.graphql b/apollo-federation/tests/query_plan/supergraphs/fragments_that_share_a_hash_but_are_not_identical_generate_their_own_fragment_definitions.graphql index a745ed6263..3e995ed7bb 100644 --- a/apollo-federation/tests/query_plan/supergraphs/fragments_that_share_a_hash_but_are_not_identical_generate_their_own_fragment_definitions.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/fragments_that_share_a_hash_but_are_not_identical_generate_their_own_fragment_definitions.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 62d7e50e5ef7c204246ba7c0cefcef3e9e5bef0c +# Composed from subgraphs with hash: d87fc8c7d88d7ddc316b4109f5c0f08a3319255b schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -12,7 +12,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -39,10 +39,19 @@ type B z: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/handle_subgraph_with_hypen_in_the_name.graphql b/apollo-federation/tests/query_plan/supergraphs/handle_subgraph_with_hypen_in_the_name.graphql index 9b7600e8a4..7206c02130 100644 --- a/apollo-federation/tests/query_plan/supergraphs/handle_subgraph_with_hypen_in_the_name.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/handle_subgraph_with_hypen_in_the_name.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: c2ea0958d4d930ae3bf3535692a966af9f3af063 +# Composed from subgraphs with hash: dceeff5b8cc9eef0d5d67d90dcad47c9d2bcdeee schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "S1", url: "none") NON_GRAPHQL_NAME @join__graph(name: "non-graphql-name", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/handle_very_non_graph_subgraph_name.graphql b/apollo-federation/tests/query_plan/supergraphs/handle_very_non_graph_subgraph_name.graphql index 3a1ae9fab2..effff2b959 100644 --- a/apollo-federation/tests/query_plan/supergraphs/handle_very_non_graph_subgraph_name.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/handle_very_non_graph_subgraph_name.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 2ad000b79369f5b833cec8d6e5e62e99db89585c +# Composed from subgraphs with hash: 008d1087d7fbef647f430c6050718ba5fd3247db schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { _42_ @join__graph(name: "42!", url: "none") S1 @join__graph(name: "S1", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/handles_case_of_key_chains_in_parallel_requires.graphql b/apollo-federation/tests/query_plan/supergraphs/handles_case_of_key_chains_in_parallel_requires.graphql index fd7953bfd3..bfbe556522 100644 --- a/apollo-federation/tests/query_plan/supergraphs/handles_case_of_key_chains_in_parallel_requires.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/handles_case_of_key_chains_in_parallel_requires.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 6f7dd1a877d5de533c98948e91197cb3526ed446 +# Composed from subgraphs with hash: 657939f9f9642f8874ed6a99f6d8f0b724c29d6b schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/handles_fragments_with_interface_field_subtyping.graphql b/apollo-federation/tests/query_plan/supergraphs/handles_fragments_with_interface_field_subtyping.graphql index 98032aadc8..06e121a504 100644 --- a/apollo-federation/tests/query_plan/supergraphs/handles_fragments_with_interface_field_subtyping.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/handles_fragments_with_interface_field_subtyping.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: cd5671782860ad7353fd02dfb07664cdc89a5809 +# Composed from subgraphs with hash: 631090cf03bf148115fe36abae4e705737e27a73 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -29,10 +29,19 @@ interface I other: I! } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/handles_mix_of_fragments_indirection_and_unions.graphql b/apollo-federation/tests/query_plan/supergraphs/handles_mix_of_fragments_indirection_and_unions.graphql index 2ff8417e3b..766e1618ad 100644 --- a/apollo-federation/tests/query_plan/supergraphs/handles_mix_of_fragments_indirection_and_unions.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/handles_mix_of_fragments_indirection_and_unions.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 0b61d90468ba75e031fdc3c1abe0ac8e87674cc7 +# Composed from subgraphs with hash: 2bc15991aebf8f895f3eb5d24040154b20447182 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -41,10 +41,19 @@ type Child id: ID! } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/handles_multiple_conditions_on_abstract_types.graphql b/apollo-federation/tests/query_plan/supergraphs/handles_multiple_conditions_on_abstract_types.graphql index 76280a249e..998237f160 100644 --- a/apollo-federation/tests/query_plan/supergraphs/handles_multiple_conditions_on_abstract_types.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/handles_multiple_conditions_on_abstract_types.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 2bb5218456c710b3aeaf9c5a9a7d87eee258917f +# Composed from subgraphs with hash: ef4b999f84fcdb4baba65f1a44c84d1e4267d948 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -36,10 +36,19 @@ type Book implements Product reviews: [Review!]! @join__field(graph: REVIEWS) } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { BOOKS @join__graph(name: "books", url: "none") MAGAZINES @join__graph(name: "magazines", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/handles_multiple_requires_involving_different_nestedness.graphql b/apollo-federation/tests/query_plan/supergraphs/handles_multiple_requires_involving_different_nestedness.graphql index 9a5c273ce0..0a3f854600 100644 --- a/apollo-federation/tests/query_plan/supergraphs/handles_multiple_requires_involving_different_nestedness.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/handles_multiple_requires_involving_different_nestedness.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 6120a9371b90c378d13d977d19bad9e17c6875cb +# Composed from subgraphs with hash: 6912a71c206209826d59e92decbc10df806b4164 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -33,10 +33,19 @@ type Item computed2: String @join__field(graph: SUBGRAPH2, requires: "user { value }") } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/handles_non_intersecting_fragment_conditions.graphql b/apollo-federation/tests/query_plan/supergraphs/handles_non_intersecting_fragment_conditions.graphql index 4be5ebe264..c1798df779 100644 --- a/apollo-federation/tests/query_plan/supergraphs/handles_non_intersecting_fragment_conditions.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/handles_non_intersecting_fragment_conditions.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: cc0d8d93561b6e20d87ae1541b16037be17333ef +# Composed from subgraphs with hash: 3c577bdcdfd12b97d2b265e5ccd5ddf286addb71 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -44,10 +44,19 @@ interface Fruit edible: Boolean! } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/handles_non_matching_value_types_under_interface_field.graphql b/apollo-federation/tests/query_plan/supergraphs/handles_non_matching_value_types_under_interface_field.graphql index 10cc68d004..1f936b1a91 100644 --- a/apollo-federation/tests/query_plan/supergraphs/handles_non_matching_value_types_under_interface_field.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/handles_non_matching_value_types_under_interface_field.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 9959b044b8b84e47c4559354eb1d87299be28495 +# Composed from subgraphs with hash: 2c44fca1dca09f3611b2c3d037001fdcb2bd607c schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -28,10 +28,19 @@ interface I s: S } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/handles_query_of_an_interface_field_for_a_specific_implementation_when_query_starts_with_interface_object.graphql b/apollo-federation/tests/query_plan/supergraphs/handles_query_of_an_interface_field_for_a_specific_implementation_when_query_starts_with_interface_object.graphql index 97189f9365..1226b3f64e 100644 --- a/apollo-federation/tests/query_plan/supergraphs/handles_query_of_an_interface_field_for_a_specific_implementation_when_query_starts_with_interface_object.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/handles_query_of_an_interface_field_for_a_specific_implementation_when_query_starts_with_interface_object.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: da551e74f6885542cefc64ed31d2b00579dce2cd +# Composed from subgraphs with hash: 2d8573a4a560444417df271ed0a39b18c366dbc0 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -51,10 +51,19 @@ interface I y: Int @join__field(graph: S2) } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "S1", url: "none") S2 @join__graph(name: "S2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/handles_requires_from_supergraph.graphql b/apollo-federation/tests/query_plan/supergraphs/handles_requires_from_supergraph.graphql index 4afa0074ca..0be24065e6 100644 --- a/apollo-federation/tests/query_plan/supergraphs/handles_requires_from_supergraph.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/handles_requires_from_supergraph.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: c980fbf8b4a77ab38f828719197c4878658aa92c +# Composed from subgraphs with hash: aa3ba9dce3c336c185aea3d559466b7d5a3d6602 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -29,10 +29,19 @@ interface I name: String } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/handles_root_operation_shareable_in_many_subgraphs.graphql b/apollo-federation/tests/query_plan/supergraphs/handles_root_operation_shareable_in_many_subgraphs.graphql index 9c2c5435dd..3cca84dfcc 100644 --- a/apollo-federation/tests/query_plan/supergraphs/handles_root_operation_shareable_in_many_subgraphs.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/handles_root_operation_shareable_in_many_subgraphs.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: dece71b67cd54bf5e3bf43988e99a638876d52e5 +# Composed from subgraphs with hash: f03aecdc91efa05b3b7a659e31c58bfcd905fb73 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/handles_simple_requires.graphql b/apollo-federation/tests/query_plan/supergraphs/handles_simple_requires.graphql index a7bbfe095a..53d20c5d7e 100644 --- a/apollo-federation/tests/query_plan/supergraphs/handles_simple_requires.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/handles_simple_requires.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: a2964ea427e664c7c007a258b54d68db9abae8f4 +# Composed from subgraphs with hash: d4af614c7debcf4bf2aa8a18f0f23f04412be82d schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/handles_spread_unions_correctly.graphql b/apollo-federation/tests/query_plan/supergraphs/handles_spread_unions_correctly.graphql index d0d026a6f3..248bcff72e 100644 --- a/apollo-federation/tests/query_plan/supergraphs/handles_spread_unions_correctly.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/handles_spread_unions_correctly.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 361121049969085d46eae818d8c9d8da18d3cf6c +# Composed from subgraphs with hash: cf0557ca376939819cf4d2f4f7e46d4b3d7836d7 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -47,10 +47,19 @@ type C c2: Int @join__field(graph: SUBGRAPH2) } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/handles_types_with_no_common_supertype_at_the_same_merge_at.graphql b/apollo-federation/tests/query_plan/supergraphs/handles_types_with_no_common_supertype_at_the_same_merge_at.graphql index 15ae958653..4a14062e26 100644 --- a/apollo-federation/tests/query_plan/supergraphs/handles_types_with_no_common_supertype_at_the_same_merge_at.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/handles_types_with_no_common_supertype_at_the_same_merge_at.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 98f941b67e6dc18205c3148808a6bce2b64c775f +# Composed from subgraphs with hash: 8a740dea36b9a39b79632385c08dd53e07af0cbb schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -40,10 +40,19 @@ type Foo y: Int @join__field(graph: SUBGRAPH2) } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/interface_interface_interaction.graphql b/apollo-federation/tests/query_plan/supergraphs/interface_interface_interaction.graphql index 4c89d271df..0a8c08838e 100644 --- a/apollo-federation/tests/query_plan/supergraphs/interface_interface_interaction.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/interface_interface_interaction.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 6ac1ca5a8c7d1596024e97bb378f1f829788fd71 +# Composed from subgraphs with hash: aad30ec98d465ca592dcfb7b6493a1721589fda7 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -60,10 +60,19 @@ interface I2 v: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/interface_interface_interaction_but_no_need_to_type_explode.graphql b/apollo-federation/tests/query_plan/supergraphs/interface_interface_interaction_but_no_need_to_type_explode.graphql index 5433f33dcf..ff8399d64c 100644 --- a/apollo-federation/tests/query_plan/supergraphs/interface_interface_interaction_but_no_need_to_type_explode.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/interface_interface_interaction_but_no_need_to_type_explode.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 5073ac23b2d2f5657028261e837e26e4370a3cf4 +# Composed from subgraphs with hash: 6bcf7c1079cc0111e6fc2f4134333b73fc319248 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -60,10 +60,19 @@ interface I2 v: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/interface_union_interaction.graphql b/apollo-federation/tests/query_plan/supergraphs/interface_union_interaction.graphql index 11afc89b98..bbeaa7ec49 100644 --- a/apollo-federation/tests/query_plan/supergraphs/interface_union_interaction.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/interface_union_interaction.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 43ca669a61b756dfac8bec5822d87393bc9f3544 +# Composed from subgraphs with hash: 92c4a98434a66db1d0a5cc563bea94c0faaa1a55 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -50,10 +50,19 @@ interface I v: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/interface_union_interaction_but_no_need_to_type_explode.graphql b/apollo-federation/tests/query_plan/supergraphs/interface_union_interaction_but_no_need_to_type_explode.graphql index 60c26dd523..5d7c1c82c4 100644 --- a/apollo-federation/tests/query_plan/supergraphs/interface_union_interaction_but_no_need_to_type_explode.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/interface_union_interaction_but_no_need_to_type_explode.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 2548adb14fdc2eacf229834ee87327873c15cb8d +# Composed from subgraphs with hash: e851cb374aa6dea60bffafd658bccd2e017af6f1 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -51,10 +51,19 @@ interface I v: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_allow_providing_fields_for_only_some_subtype.graphql b/apollo-federation/tests/query_plan/supergraphs/it_allow_providing_fields_for_only_some_subtype.graphql index fcbc7f2aa3..4f81762ce3 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_allow_providing_fields_for_only_some_subtype.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_allow_providing_fields_for_only_some_subtype.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 7225f76e0549cfa72d92ea3d954fbfa4f5325cff +# Composed from subgraphs with hash: 799c11349d958543e444e53c4ed186a8e7f820f6 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -29,10 +29,19 @@ interface I b: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_avoid_fragments_usable_only_once.graphql b/apollo-federation/tests/query_plan/supergraphs/it_avoid_fragments_usable_only_once.graphql index 629427d8e7..48a62f633e 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_avoid_fragments_usable_only_once.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_avoid_fragments_usable_only_once.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 57cf5fd9ee4bd6e69d9976aef7ff289a74c757c4 +# Composed from subgraphs with hash: 3ea57c667516dce90ad8a2331832f8be1f86f197 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_avoids_buffering_interface_object_results_that_may_have_to_be_filtered_with_lists.graphql b/apollo-federation/tests/query_plan/supergraphs/it_avoids_buffering_interface_object_results_that_may_have_to_be_filtered_with_lists.graphql index b989cee25c..8a8283144b 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_avoids_buffering_interface_object_results_that_may_have_to_be_filtered_with_lists.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_avoids_buffering_interface_object_results_that_may_have_to_be_filtered_with_lists.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 885b71f276ed574d24895695bddb2bd130640f65 +# Composed from subgraphs with hash: 803bcb0fbcd87892a96ce14b10f3c11256f2870b schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -48,10 +48,19 @@ interface I expansiveField: String @join__field(graph: S1) } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "S1", url: "none") S2 @join__graph(name: "S2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_can_require_at_inaccessible_fields.graphql b/apollo-federation/tests/query_plan/supergraphs/it_can_require_at_inaccessible_fields.graphql index 45bca01a72..22e98bf368 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_can_require_at_inaccessible_fields.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_can_require_at_inaccessible_fields.graphql @@ -1,8 +1,8 @@ -# Composed from subgraphs with hash: 49f8443a5ff323a1ffed6b7122a1d61e6225d235 +# Composed from subgraphs with hash: 8d7a727bb1c4430ee3ee6df729a5c72ac0a7e181 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) - @link(url: "https://specs.apollo.dev/inaccessible/v0.2", for: SECURITY) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) + @link(url: "https://specs.apollo.dev/inaccessible/v0.2", import: ["@inaccessible"], for: SECURITY) { query: Query } @@ -13,7 +13,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -25,10 +25,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_does_not_needlessly_consider_options_for_typename.graphql b/apollo-federation/tests/query_plan/supergraphs/it_does_not_needlessly_consider_options_for_typename.graphql index 82876af15e..e00fa476eb 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_does_not_needlessly_consider_options_for_typename.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_does_not_needlessly_consider_options_for_typename.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: ee7dda36e9dc663f9750f86da48822e8f6f6ea8f +# Composed from subgraphs with hash: 665427c4bfc0c14e12d92d34229628661820a58b schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_does_not_override_unset_labels_on_entity_fields.graphql b/apollo-federation/tests/query_plan/supergraphs/it_does_not_override_unset_labels_on_entity_fields.graphql index cda69fb905..054bdac9a1 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_does_not_override_unset_labels_on_entity_fields.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_does_not_override_unset_labels_on_entity_fields.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: ea1fd23b849053c0b7cfbf9a192453c71e70f889 +# Composed from subgraphs with hash: 898d84a7356419fd51e15c565a45b3ba121f272f schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "s1", url: "none") S2 @join__graph(name: "s2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_does_not_override_unset_labels_on_nested_entity_fields.graphql b/apollo-federation/tests/query_plan/supergraphs/it_does_not_override_unset_labels_on_nested_entity_fields.graphql index cda69fb905..054bdac9a1 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_does_not_override_unset_labels_on_nested_entity_fields.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_does_not_override_unset_labels_on_nested_entity_fields.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: ea1fd23b849053c0b7cfbf9a192453c71e70f889 +# Composed from subgraphs with hash: 898d84a7356419fd51e15c565a45b3ba121f272f schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "s1", url: "none") S2 @join__graph(name: "s2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_does_not_override_unset_labels_on_root_fields.graphql b/apollo-federation/tests/query_plan/supergraphs/it_does_not_override_unset_labels_on_root_fields.graphql index 206487ca49..b627614bd2 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_does_not_override_unset_labels_on_root_fields.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_does_not_override_unset_labels_on_root_fields.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: b409284c35003f62c7c83675734478b1970effb2 +# Composed from subgraphs with hash: 876e9aeacdff38ab69fae92ab4830e10f28b6fd3 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "s1", url: "none") S2 @join__graph(name: "s2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_does_not_try_to_apply_fragments_that_are_not_valid_for_the_subgraph.graphql b/apollo-federation/tests/query_plan/supergraphs/it_does_not_try_to_apply_fragments_that_are_not_valid_for_the_subgraph.graphql index d0358af17b..2f15689f7a 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_does_not_try_to_apply_fragments_that_are_not_valid_for_the_subgraph.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_does_not_try_to_apply_fragments_that_are_not_valid_for_the_subgraph.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 11ffa462805ad28daecca693ed1a45d931d3cac8 +# Composed from subgraphs with hash: 48933e92f90d5670a9f24349a530c214cf89fbbc schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -30,10 +30,19 @@ interface I b: Int @join__field(graph: SUBGRAPH2) } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_executes_mutation_operations_in_sequence.graphql b/apollo-federation/tests/query_plan/supergraphs/it_executes_mutation_operations_in_sequence.graphql index c8a3b06e68..10ae0d54ce 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_executes_mutation_operations_in_sequence.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_executes_mutation_operations_in_sequence.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: ff6534336a58b9a72232e43fdb66c4769ac4ae66 +# Composed from subgraphs with hash: 167da40652f362ea1ee23360c16a7a706369148d schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query mutation: Mutation @@ -11,7 +11,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -23,10 +23,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_handes_diamond_shape_depedencies.graphql b/apollo-federation/tests/query_plan/supergraphs/it_handes_diamond_shape_depedencies.graphql index b410e60027..27fd59a787 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_handes_diamond_shape_depedencies.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_handes_diamond_shape_depedencies.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 2a90ec602bc41c24462757dc66b2e37e1d96dbf4 +# Composed from subgraphs with hash: a7228e28b556a2f72545f7993f3b68d25944b04d schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { A @join__graph(name: "A", url: "none") B @join__graph(name: "B", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_handles_a_simple_at_requires_triggered_within_a_conditional.graphql b/apollo-federation/tests/query_plan/supergraphs/it_handles_a_simple_at_requires_triggered_within_a_conditional.graphql index 7cd49ac90f..4d30aa4ed6 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_handles_a_simple_at_requires_triggered_within_a_conditional.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_handles_a_simple_at_requires_triggered_within_a_conditional.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 88de1465b4ef08a76a910cff26136f931b69eca4 +# Composed from subgraphs with hash: a5459e4976ee54fb002ab54de666b70cd01c9805 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_handles_an_at_requires_triggered_conditionally.graphql b/apollo-federation/tests/query_plan/supergraphs/it_handles_an_at_requires_triggered_conditionally.graphql index 7cd49ac90f..4d30aa4ed6 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_handles_an_at_requires_triggered_conditionally.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_handles_an_at_requires_triggered_conditionally.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 88de1465b4ef08a76a910cff26136f931b69eca4 +# Composed from subgraphs with hash: a5459e4976ee54fb002ab54de666b70cd01c9805 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_handles_an_at_requires_where_multiple_conditional_are_involved.graphql b/apollo-federation/tests/query_plan/supergraphs/it_handles_an_at_requires_where_multiple_conditional_are_involved.graphql index 9442a08abf..91e32419cd 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_handles_an_at_requires_where_multiple_conditional_are_involved.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_handles_an_at_requires_where_multiple_conditional_are_involved.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 213ee593775b6e4a22a852a35da688bc2e85d710 +# Composed from subgraphs with hash: 8d562727336acf24ddefa337d51f03c88d6634de schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -39,10 +39,19 @@ type B c: Int @join__field(graph: SUBGRAPH3, requires: "required") } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_handles_complex_require_chain.graphql b/apollo-federation/tests/query_plan/supergraphs/it_handles_complex_require_chain.graphql index 8fbe10543a..8070b8da37 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_handles_complex_require_chain.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_handles_complex_require_chain.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: eeb0b0963b210e2f82e6f40f535037882afb96db +# Composed from subgraphs with hash: f82048b558e108214a7bd9b888b7cd19868588b4 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -40,10 +40,19 @@ type Inner4Type inner4_nested: Int! @join__field(graph: SUBGRAPH5, requires: "inner4_required") } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_handles_fragment_rebasing_in_a_subgraph_where_some_subtyping_relation_differs.graphql b/apollo-federation/tests/query_plan/supergraphs/it_handles_fragment_rebasing_in_a_subgraph_where_some_subtyping_relation_differs.graphql index 39f730f702..8aaa3f274f 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_handles_fragment_rebasing_in_a_subgraph_where_some_subtyping_relation_differs.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_handles_fragment_rebasing_in_a_subgraph_where_some_subtyping_relation_differs.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 0545139260d6549f4e32906bce43c37742fdff80 +# Composed from subgraphs with hash: b2221050efb89f6e4df71823675d2ea1fbe66a31 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -38,10 +38,19 @@ type Inner implements I w: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_handles_fragment_rebasing_in_a_subgraph_where_some_union_membership_relation_differs.graphql b/apollo-federation/tests/query_plan/supergraphs/it_handles_fragment_rebasing_in_a_subgraph_where_some_union_membership_relation_differs.graphql index 8706c2af1e..3ffdb5403e 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_handles_fragment_rebasing_in_a_subgraph_where_some_union_membership_relation_differs.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_handles_fragment_rebasing_in_a_subgraph_where_some_union_membership_relation_differs.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 2be5cb3476eaeac718ff9d77f717b70fe9f344a2 +# Composed from subgraphs with hash: 94b7e94d03865ae730e8e7b6165d4deeed218c72 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -29,10 +29,19 @@ type Inner w: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_handles_fragments_with_one_non_leaf_field.graphql b/apollo-federation/tests/query_plan/supergraphs/it_handles_fragments_with_one_non_leaf_field.graphql index a745ed6263..3e995ed7bb 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_handles_fragments_with_one_non_leaf_field.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_handles_fragments_with_one_non_leaf_field.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 62d7e50e5ef7c204246ba7c0cefcef3e9e5bef0c +# Composed from subgraphs with hash: d87fc8c7d88d7ddc316b4109f5c0f08a3319255b schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -12,7 +12,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -39,10 +39,19 @@ type B z: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/it_handles_interface_object_in_nested_entity.graphql b/apollo-federation/tests/query_plan/supergraphs/it_handles_interface_object_in_nested_entity.graphql index fe5bef73a1..15bb01ded8 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_handles_interface_object_in_nested_entity.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_handles_interface_object_in_nested_entity.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 3881ebaea69bd73941780a88cffefd7f909c77d1 +# Composed from subgraphs with hash: 2dd159285f3b564dab13310cf19c753575fbf1d6 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -49,10 +49,19 @@ interface I a: Int @join__field(graph: S2) } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "S1", url: "none") S2 @join__graph(name: "S2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_handles_interface_object_input_rewrites_when_cloning_dependency_graph.graphql b/apollo-federation/tests/query_plan/supergraphs/it_handles_interface_object_input_rewrites_when_cloning_dependency_graph.graphql index 41b8deead2..19a4cfd986 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_handles_interface_object_input_rewrites_when_cloning_dependency_graph.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_handles_interface_object_input_rewrites_when_cloning_dependency_graph.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 3799eb12e6387413ef90a73d8848b5c48e40cbca +# Composed from subgraphs with hash: 1b82052bbef41bea0b8cc6650bfd42149af666b5 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -31,10 +31,19 @@ interface I i3: Int @join__field(graph: S2) } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "S1", url: "none") S2 @join__graph(name: "S2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_handles_longer_require_chain.graphql b/apollo-federation/tests/query_plan/supergraphs/it_handles_longer_require_chain.graphql index 0d81bb4ee6..1da9d8d72a 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_handles_longer_require_chain.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_handles_longer_require_chain.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 00470b1d89f783a11f9b05f82d8377c0d5e3f89d +# Composed from subgraphs with hash: 13b9f66e51175713b45f58b5c9cb1bf93123c731 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH10 @join__graph(name: "Subgraph10", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_handles_multiple_requires_with_multiple_fetches.graphql b/apollo-federation/tests/query_plan/supergraphs/it_handles_multiple_requires_with_multiple_fetches.graphql index 57e31110e1..91bd2a3ab0 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_handles_multiple_requires_with_multiple_fetches.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_handles_multiple_requires_with_multiple_fetches.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 55b2cd6d674b743ae99fa918dce065759899f51d +# Composed from subgraphs with hash: d9d299269fc1b12c334504cd1ba44d173360c498 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -31,10 +31,19 @@ interface I name: String! } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "s1", url: "none") S2 @join__graph(name: "s2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_handles_multiple_requires_within_the_same_entity_fetch.graphql b/apollo-federation/tests/query_plan/supergraphs/it_handles_multiple_requires_within_the_same_entity_fetch.graphql index 8beeb189bd..48dfe2a166 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_handles_multiple_requires_within_the_same_entity_fetch.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_handles_multiple_requires_within_the_same_entity_fetch.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 151440cab35934f002ebab673ce5f8bd86966772 +# Composed from subgraphs with hash: 6670829507adac060bea0af75f139243611c4359 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -30,10 +30,19 @@ interface I g: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_handles_nested_fragment_generation.graphql b/apollo-federation/tests/query_plan/supergraphs/it_handles_nested_fragment_generation.graphql index a745ed6263..3e995ed7bb 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_handles_nested_fragment_generation.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_handles_nested_fragment_generation.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 62d7e50e5ef7c204246ba7c0cefcef3e9e5bef0c +# Composed from subgraphs with hash: d87fc8c7d88d7ddc316b4109f5c0f08a3319255b schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -12,7 +12,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -39,10 +39,19 @@ type B z: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/it_handles_progressive_override_on_entity_fields.graphql b/apollo-federation/tests/query_plan/supergraphs/it_handles_progressive_override_on_entity_fields.graphql index cda69fb905..054bdac9a1 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_handles_progressive_override_on_entity_fields.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_handles_progressive_override_on_entity_fields.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: ea1fd23b849053c0b7cfbf9a192453c71e70f889 +# Composed from subgraphs with hash: 898d84a7356419fd51e15c565a45b3ba121f272f schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "s1", url: "none") S2 @join__graph(name: "s2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_handles_progressive_override_on_nested_entity_fields.graphql b/apollo-federation/tests/query_plan/supergraphs/it_handles_progressive_override_on_nested_entity_fields.graphql index cda69fb905..054bdac9a1 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_handles_progressive_override_on_nested_entity_fields.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_handles_progressive_override_on_nested_entity_fields.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: ea1fd23b849053c0b7cfbf9a192453c71e70f889 +# Composed from subgraphs with hash: 898d84a7356419fd51e15c565a45b3ba121f272f schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "s1", url: "none") S2 @join__graph(name: "s2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_handles_progressive_override_on_root_fields.graphql b/apollo-federation/tests/query_plan/supergraphs/it_handles_progressive_override_on_root_fields.graphql index 206487ca49..b627614bd2 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_handles_progressive_override_on_root_fields.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_handles_progressive_override_on_root_fields.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: b409284c35003f62c7c83675734478b1970effb2 +# Composed from subgraphs with hash: 876e9aeacdff38ab69fae92ab4830e10f28b6fd3 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "s1", url: "none") S2 @join__graph(name: "s2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_handles_require_chain_not_ending_in_original_group.graphql b/apollo-federation/tests/query_plan/supergraphs/it_handles_require_chain_not_ending_in_original_group.graphql index 3d4964b712..53ae96662b 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_handles_require_chain_not_ending_in_original_group.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_handles_require_chain_not_ending_in_original_group.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: ff92849ceafa9aaccab960b8b5ce0e98a13e6a00 +# Composed from subgraphs with hash: b700dc9de06af55918612c3c23975613c7625ab0 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_handles_requires_on_concrete_type_of_field_provided_by_interface_object.graphql b/apollo-federation/tests/query_plan/supergraphs/it_handles_requires_on_concrete_type_of_field_provided_by_interface_object.graphql index aae7fd038a..ac4b478cdf 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_handles_requires_on_concrete_type_of_field_provided_by_interface_object.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_handles_requires_on_concrete_type_of_field_provided_by_interface_object.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 209a0436ca69cb640450ef4fc7c204a5b5fc6058 +# Composed from subgraphs with hash: 2a2bbbfde2d57ed4fb71a1b63682f2c3ea5f27e5 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -47,10 +47,19 @@ interface I x: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "S1", url: "none") S2 @join__graph(name: "S2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_handles_simple_require_chain.graphql b/apollo-federation/tests/query_plan/supergraphs/it_handles_simple_require_chain.graphql index b076bc92fe..119e9a6802 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_handles_simple_require_chain.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_handles_simple_require_chain.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 244af51d2d8ba7d87e4b9fec74bbb49dc7b00e4d +# Composed from subgraphs with hash: 457e28f8e650826536a34aec9a0d7e7f938609a2 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_identifies_and_reuses_equivalent_fragments_that_arent_identical.graphql b/apollo-federation/tests/query_plan/supergraphs/it_identifies_and_reuses_equivalent_fragments_that_arent_identical.graphql index a745ed6263..3e995ed7bb 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_identifies_and_reuses_equivalent_fragments_that_arent_identical.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_identifies_and_reuses_equivalent_fragments_that_arent_identical.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 62d7e50e5ef7c204246ba7c0cefcef3e9e5bef0c +# Composed from subgraphs with hash: d87fc8c7d88d7ddc316b4109f5c0f08a3319255b schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -12,7 +12,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -39,10 +39,19 @@ type B z: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/it_migrates_skip_include.graphql b/apollo-federation/tests/query_plan/supergraphs/it_migrates_skip_include.graphql index a745ed6263..3e995ed7bb 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_migrates_skip_include.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_migrates_skip_include.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 62d7e50e5ef7c204246ba7c0cefcef3e9e5bef0c +# Composed from subgraphs with hash: d87fc8c7d88d7ddc316b4109f5c0f08a3319255b schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -12,7 +12,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -39,10 +39,19 @@ type B z: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/it_overrides_f1_to_s3_when_label_is_provided.graphql b/apollo-federation/tests/query_plan/supergraphs/it_overrides_f1_to_s3_when_label_is_provided.graphql index 8ee0521f3b..e8b4cd762b 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_overrides_f1_to_s3_when_label_is_provided.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_overrides_f1_to_s3_when_label_is_provided.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 5f73656f77e5320839ceba43507ea13060eea5e1 +# Composed from subgraphs with hash: 58136a8ddfdf60b78598ff5b86f5b4ae3193a41c schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "S1", url: "none") S2 @join__graph(name: "S2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_overrides_to_s2_when_label_is_provided.graphql b/apollo-federation/tests/query_plan/supergraphs/it_overrides_to_s2_when_label_is_provided.graphql index 8ee0521f3b..e8b4cd762b 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_overrides_to_s2_when_label_is_provided.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_overrides_to_s2_when_label_is_provided.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 5f73656f77e5320839ceba43507ea13060eea5e1 +# Composed from subgraphs with hash: 58136a8ddfdf60b78598ff5b86f5b4ae3193a41c schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "S1", url: "none") S2 @join__graph(name: "S2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_preservers_aliased_typename.graphql b/apollo-federation/tests/query_plan/supergraphs/it_preservers_aliased_typename.graphql index adc483ebe7..c9885e4c8e 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_preservers_aliased_typename.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_preservers_aliased_typename.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: d7fe5a716fee436faefb289f7ba4a8bd05bd7d34 +# Composed from subgraphs with hash: ce2557f5278c94808d1e49ad488bf60d0355e98d schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/it_preserves_directives_when_fragment_is_reused.graphql b/apollo-federation/tests/query_plan/supergraphs/it_preserves_directives_when_fragment_is_reused.graphql index 9aa130fc7f..95316d4353 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_preserves_directives_when_fragment_is_reused.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_preserves_directives_when_fragment_is_reused.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 75955b009750aae84f92b194eddcb553f0e44656 +# Composed from subgraphs with hash: 136ac120ab3c0a9b8ea4cb22cb440886a1b4a961 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/it_preserves_directives_when_fragment_not_used.graphql b/apollo-federation/tests/query_plan/supergraphs/it_preserves_directives_when_fragment_not_used.graphql index 9aa130fc7f..95316d4353 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_preserves_directives_when_fragment_not_used.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_preserves_directives_when_fragment_not_used.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 75955b009750aae84f92b194eddcb553f0e44656 +# Composed from subgraphs with hash: 136ac120ab3c0a9b8ea4cb22cb440886a1b4a961 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/it_preserves_nested_fragments_when_outer_one_has_directives_and_is_eliminated.graphql b/apollo-federation/tests/query_plan/supergraphs/it_preserves_nested_fragments_when_outer_one_has_directives_and_is_eliminated.graphql index a12329a27d..7b9af26713 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_preserves_nested_fragments_when_outer_one_has_directives_and_is_eliminated.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_preserves_nested_fragments_when_outer_one_has_directives_and_is_eliminated.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: f580fdce2d5df285d6e12633d4355b51e2fd52fd +# Composed from subgraphs with hash: fd162a5fc982fc2cd0a8d33e271831822b681137 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/it_preserves_typename_with_directives.graphql b/apollo-federation/tests/query_plan/supergraphs/it_preserves_typename_with_directives.graphql index 79dbbde767..b812bb841a 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_preserves_typename_with_directives.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_preserves_typename_with_directives.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 5781ed69d05761a7c894a8aac04728581a2475d9 +# Composed from subgraphs with hash: feb9a6756ae190fe90dc2297767c2b4b08fb56a9 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/it_require_of_multiple_field_when_one_is_also_a_key_to_reach_another.graphql b/apollo-federation/tests/query_plan/supergraphs/it_require_of_multiple_field_when_one_is_also_a_key_to_reach_another.graphql index 66be42e56a..a291d321a8 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_require_of_multiple_field_when_one_is_also_a_key_to_reach_another.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_require_of_multiple_field_when_one_is_also_a_key_to_reach_another.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 3766e23446d1f1881fb155fefa8036726c6f34c4 +# Composed from subgraphs with hash: 01a8e1dfb199705050c7be5bc0f6efb3da20e92e schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { A @join__graph(name: "A", url: "none") B @join__graph(name: "B", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_resolves_f1_in_s1_when_label_is_not_provided.graphql b/apollo-federation/tests/query_plan/supergraphs/it_resolves_f1_in_s1_when_label_is_not_provided.graphql index 8ee0521f3b..e8b4cd762b 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_resolves_f1_in_s1_when_label_is_not_provided.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_resolves_f1_in_s1_when_label_is_not_provided.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 5f73656f77e5320839ceba43507ea13060eea5e1 +# Composed from subgraphs with hash: 58136a8ddfdf60b78598ff5b86f5b4ae3193a41c schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "S1", url: "none") S2 @join__graph(name: "S2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_resolves_in_s1_when_label_is_not_provided.graphql b/apollo-federation/tests/query_plan/supergraphs/it_resolves_in_s1_when_label_is_not_provided.graphql index 8ee0521f3b..e8b4cd762b 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_resolves_in_s1_when_label_is_not_provided.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_resolves_in_s1_when_label_is_not_provided.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 5f73656f77e5320839ceba43507ea13060eea5e1 +# Composed from subgraphs with hash: 58136a8ddfdf60b78598ff5b86f5b4ae3193a41c schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "S1", url: "none") S2 @join__graph(name: "S2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_respects_generate_query_fragments_option.graphql b/apollo-federation/tests/query_plan/supergraphs/it_respects_generate_query_fragments_option.graphql index a745ed6263..3e995ed7bb 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_respects_generate_query_fragments_option.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_respects_generate_query_fragments_option.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 62d7e50e5ef7c204246ba7c0cefcef3e9e5bef0c +# Composed from subgraphs with hash: d87fc8c7d88d7ddc316b4109f5c0f08a3319255b schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -12,7 +12,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -39,10 +39,19 @@ type B z: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/it_works_on_interfaces.graphql b/apollo-federation/tests/query_plan/supergraphs/it_works_on_interfaces.graphql index a7d3b59025..9e11724dcd 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_works_on_interfaces.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_works_on_interfaces.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: d654244e34da1e73ea47f5325e371614408d38ae +# Composed from subgraphs with hash: d2db7329336a011305d153d60031e5fe634adedb schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -28,10 +28,19 @@ interface I v: Value } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_works_on_unions.graphql b/apollo-federation/tests/query_plan/supergraphs/it_works_on_unions.graphql index bb44229f8d..51f7ac8d5f 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_works_on_unions.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_works_on_unions.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 87210bff4bf720ff0fe68c22dae1d3e5520d7980 +# Composed from subgraphs with hash: aa33c34a78654942627b836a960f9da314ca826e schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_works_with_nested_fragments_1.graphql b/apollo-federation/tests/query_plan/supergraphs/it_works_with_nested_fragments_1.graphql index 3b5fe2a129..19aedf2358 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_works_with_nested_fragments_1.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_works_with_nested_fragments_1.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 18fc379a3170731963d1ec9f54f8b002b0f5d874 +# Composed from subgraphs with hash: 0b52a1cc2cdc06e7b2bb3c438672662d0f80de68 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -64,10 +64,19 @@ interface Foo child2: Foo } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/it_works_with_nested_fragments_when_only_the_nested_fragment_gets_preserved.graphql b/apollo-federation/tests/query_plan/supergraphs/it_works_with_nested_fragments_when_only_the_nested_fragment_gets_preserved.graphql index ef1c275632..0d1594dcca 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_works_with_nested_fragments_when_only_the_nested_fragment_gets_preserved.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_works_with_nested_fragments_when_only_the_nested_fragment_gets_preserved.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 197c4ea5c04d17ec60cb084c49efe2f9d662079b +# Composed from subgraphs with hash: af8642bd2cc335a2823e7c95f48ce005d3c809f0 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/it_works_with_nested_provides.graphql b/apollo-federation/tests/query_plan/supergraphs/it_works_with_nested_provides.graphql index 581e7c764b..9217e787f0 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_works_with_nested_provides.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_works_with_nested_provides.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: fb1513832764f051dd663a966309809fb58e4519 +# Composed from subgraphs with hash: d2ea3c5c49010cc58bc83d22cf064d8e307ad23e schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/it_works_with_type_condition_even_for_types_only_reachable_by_the_at_provides.graphql b/apollo-federation/tests/query_plan/supergraphs/it_works_with_type_condition_even_for_types_only_reachable_by_the_at_provides.graphql index 1b20db25a4..ec70801803 100644 --- a/apollo-federation/tests/query_plan/supergraphs/it_works_with_type_condition_even_for_types_only_reachable_by_the_at_provides.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/it_works_with_type_condition_even_for_types_only_reachable_by_the_at_provides.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 0556f39f18edcd446ffee2af4cec39d408bf7b7d +# Composed from subgraphs with hash: bb2856a3e0e2f066120553ce903effcc593c7907 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -37,10 +37,19 @@ interface I a: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/key_where_at_external_is_not_at_top_level_of_selection_of_requires.graphql b/apollo-federation/tests/query_plan/supergraphs/key_where_at_external_is_not_at_top_level_of_selection_of_requires.graphql index c5c7c136a3..827ec19db0 100644 --- a/apollo-federation/tests/query_plan/supergraphs/key_where_at_external_is_not_at_top_level_of_selection_of_requires.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/key_where_at_external_is_not_at_top_level_of_selection_of_requires.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 3035e486a3ec94c91ff841c2eb464b287fead177 +# Composed from subgraphs with hash: 3517f40ed88e4d3fad368bc9dc78a52173c3f827 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { A @join__graph(name: "A", url: "none") B @join__graph(name: "B", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/merging_skip_and_include_directives_multiple_applications_differing_order.graphql b/apollo-federation/tests/query_plan/supergraphs/merging_skip_and_include_directives_multiple_applications_differing_order.graphql index 80f6562f18..8971d93a09 100644 --- a/apollo-federation/tests/query_plan/supergraphs/merging_skip_and_include_directives_multiple_applications_differing_order.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/merging_skip_and_include_directives_multiple_applications_differing_order.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: fbbe470b5e40af130de42043f74772ec30ee60ff +# Composed from subgraphs with hash: 00f8a26b066b234394aed3ca1e140a534b0364a8 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -29,10 +29,19 @@ type Hello goodbye: String! } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPHSKIP @join__graph(name: "SubgraphSkip", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/merging_skip_and_include_directives_multiple_applications_differing_quantity.graphql b/apollo-federation/tests/query_plan/supergraphs/merging_skip_and_include_directives_multiple_applications_differing_quantity.graphql index 80f6562f18..8971d93a09 100644 --- a/apollo-federation/tests/query_plan/supergraphs/merging_skip_and_include_directives_multiple_applications_differing_quantity.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/merging_skip_and_include_directives_multiple_applications_differing_quantity.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: fbbe470b5e40af130de42043f74772ec30ee60ff +# Composed from subgraphs with hash: 00f8a26b066b234394aed3ca1e140a534b0364a8 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -29,10 +29,19 @@ type Hello goodbye: String! } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPHSKIP @join__graph(name: "SubgraphSkip", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/merging_skip_and_include_directives_multiple_applications_identical.graphql b/apollo-federation/tests/query_plan/supergraphs/merging_skip_and_include_directives_multiple_applications_identical.graphql index 80f6562f18..8971d93a09 100644 --- a/apollo-federation/tests/query_plan/supergraphs/merging_skip_and_include_directives_multiple_applications_identical.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/merging_skip_and_include_directives_multiple_applications_identical.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: fbbe470b5e40af130de42043f74772ec30ee60ff +# Composed from subgraphs with hash: 00f8a26b066b234394aed3ca1e140a534b0364a8 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -29,10 +29,19 @@ type Hello goodbye: String! } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPHSKIP @join__graph(name: "SubgraphSkip", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/merging_skip_and_include_directives_with_fragment.graphql b/apollo-federation/tests/query_plan/supergraphs/merging_skip_and_include_directives_with_fragment.graphql index 80f6562f18..8971d93a09 100644 --- a/apollo-federation/tests/query_plan/supergraphs/merging_skip_and_include_directives_with_fragment.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/merging_skip_and_include_directives_with_fragment.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: fbbe470b5e40af130de42043f74772ec30ee60ff +# Composed from subgraphs with hash: 00f8a26b066b234394aed3ca1e140a534b0364a8 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -29,10 +29,19 @@ type Hello goodbye: String! } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPHSKIP @join__graph(name: "SubgraphSkip", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/merging_skip_and_include_directives_without_fragment.graphql b/apollo-federation/tests/query_plan/supergraphs/merging_skip_and_include_directives_without_fragment.graphql index 80f6562f18..8971d93a09 100644 --- a/apollo-federation/tests/query_plan/supergraphs/merging_skip_and_include_directives_without_fragment.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/merging_skip_and_include_directives_without_fragment.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: fbbe470b5e40af130de42043f74772ec30ee60ff +# Composed from subgraphs with hash: 00f8a26b066b234394aed3ca1e140a534b0364a8 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -29,10 +29,19 @@ type Hello goodbye: String! } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPHSKIP @join__graph(name: "SubgraphSkip", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/multiplication_overflow_in_reduce_options_if_needed.graphql b/apollo-federation/tests/query_plan/supergraphs/multiplication_overflow_in_reduce_options_if_needed.graphql index 42f3b4b125..a1f388ed61 100644 --- a/apollo-federation/tests/query_plan/supergraphs/multiplication_overflow_in_reduce_options_if_needed.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/multiplication_overflow_in_reduce_options_if_needed.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 91d4d0661d413b60ae2ed463c074c4180d7b849e +# Composed from subgraphs with hash: a9236eee956ed7fc219b2212696478159ced7eea schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/nested_fragment_with_intersecting_parent_type_and_directive_condition.graphql b/apollo-federation/tests/query_plan/supergraphs/nested_fragment_with_intersecting_parent_type_and_directive_condition.graphql index 1e2a373495..6c5379daff 100644 --- a/apollo-federation/tests/query_plan/supergraphs/nested_fragment_with_intersecting_parent_type_and_directive_condition.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/nested_fragment_with_intersecting_parent_type_and_directive_condition.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: e2393609250b71261acc4089006bc8a14627d488 +# Composed from subgraphs with hash: 60b6f32feef51579a2b534cc06e803a7fd2aa5d8 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -37,10 +37,19 @@ interface I2 title: String } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { A @join__graph(name: "A", url: "none") B @join__graph(name: "B", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/non_adjacent_mutations_do_not_get_merged.graphql b/apollo-federation/tests/query_plan/supergraphs/non_adjacent_mutations_do_not_get_merged.graphql index ae84cc8ed8..6764677f0c 100644 --- a/apollo-federation/tests/query_plan/supergraphs/non_adjacent_mutations_do_not_get_merged.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/non_adjacent_mutations_do_not_get_merged.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 54adb76945715a2ce0e068d2635d71ca4166b289 +# Composed from subgraphs with hash: e7bdd5a089836a642476b6cb289e21dfe867b4ab schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query mutation: Mutation @@ -11,7 +11,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -32,10 +32,19 @@ type Foo baz: Int @join__field(graph: SUBGRAPHB) } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPHA @join__graph(name: "SubgraphA", url: "none") SUBGRAPHB @join__graph(name: "SubgraphB", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/only_uses_an_interface_object_if_it_can.graphql b/apollo-federation/tests/query_plan/supergraphs/only_uses_an_interface_object_if_it_can.graphql index 97189f9365..1226b3f64e 100644 --- a/apollo-federation/tests/query_plan/supergraphs/only_uses_an_interface_object_if_it_can.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/only_uses_an_interface_object_if_it_can.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: da551e74f6885542cefc64ed31d2b00579dce2cd +# Composed from subgraphs with hash: 2d8573a4a560444417df271ed0a39b18c366dbc0 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -51,10 +51,19 @@ interface I y: Int @join__field(graph: S2) } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "S1", url: "none") S2 @join__graph(name: "S2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/pick_keys_that_minimize_fetches.graphql b/apollo-federation/tests/query_plan/supergraphs/pick_keys_that_minimize_fetches.graphql index dc51cbcdcc..6020cd5b7f 100644 --- a/apollo-federation/tests/query_plan/supergraphs/pick_keys_that_minimize_fetches.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/pick_keys_that_minimize_fetches.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 454b3fc41adce04fc670f06030743d521d09096d +# Composed from subgraphs with hash: 477d072dba9eac87f14e07f061eef2003d803291 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -37,10 +37,19 @@ type Currency sign: String! } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/redundant_typename_for_inline_fragments_without_type_condition.graphql b/apollo-federation/tests/query_plan/supergraphs/redundant_typename_for_inline_fragments_without_type_condition.graphql index 923d850187..eb0a2e0d5d 100644 --- a/apollo-federation/tests/query_plan/supergraphs/redundant_typename_for_inline_fragments_without_type_condition.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/redundant_typename_for_inline_fragments_without_type_condition.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: f02b27ab5f92e1e70c07bf7d5ce65e620637ef35 +# Composed from subgraphs with hash: 926811cf9f8aa69f79e2143ad129969648ca0b75 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/respects_query_planner_option_reuse_query_fragments_false.graphql b/apollo-federation/tests/query_plan/supergraphs/respects_query_planner_option_reuse_query_fragments_false.graphql index 003c7fc0ec..000490dd41 100644 --- a/apollo-federation/tests/query_plan/supergraphs/respects_query_planner_option_reuse_query_fragments_false.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/respects_query_planner_option_reuse_query_fragments_false.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 4fc759c1b39c54d520a6868db43813e4a38bbaf3 +# Composed from subgraphs with hash: d072d5c57a6c4387ebe527d2ad00a30cbceac34b schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -29,10 +29,19 @@ type A y: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/respects_query_planner_option_reuse_query_fragments_true.graphql b/apollo-federation/tests/query_plan/supergraphs/respects_query_planner_option_reuse_query_fragments_true.graphql index 003c7fc0ec..000490dd41 100644 --- a/apollo-federation/tests/query_plan/supergraphs/respects_query_planner_option_reuse_query_fragments_true.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/respects_query_planner_option_reuse_query_fragments_true.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 4fc759c1b39c54d520a6868db43813e4a38bbaf3 +# Composed from subgraphs with hash: d072d5c57a6c4387ebe527d2ad00a30cbceac34b schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -29,10 +29,19 @@ type A y: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/same_as_js_router798.graphql b/apollo-federation/tests/query_plan/supergraphs/same_as_js_router798.graphql index 6895c4bf96..ff31b706b2 100644 --- a/apollo-federation/tests/query_plan/supergraphs/same_as_js_router798.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/same_as_js_router798.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: ee7fce9eb672edf9b036a25bcae0b056ccf5f451 +# Composed from subgraphs with hash: 3606ac3a1b1064419fe78425582e73b5ce3b5369 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -28,10 +28,19 @@ interface Interface a: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-federation/tests/query_plan/supergraphs/selections_are_not_overwritten_after_removing_directives.graphql b/apollo-federation/tests/query_plan/supergraphs/selections_are_not_overwritten_after_removing_directives.graphql index 6d2137b561..fc9e5cad10 100644 --- a/apollo-federation/tests/query_plan/supergraphs/selections_are_not_overwritten_after_removing_directives.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/selections_are_not_overwritten_after_removing_directives.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 56ab651bf30bcb3ac7a9fb826fa6b03a57288859 +# Composed from subgraphs with hash: 0d8bac977a97888c29d1c90cff65ea818522aeec schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -38,10 +38,19 @@ type Foo bar: Bar } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/skip_type_explosion_early_if_unnecessary.graphql b/apollo-federation/tests/query_plan/supergraphs/skip_type_explosion_early_if_unnecessary.graphql index c0db4184d4..4802078dad 100644 --- a/apollo-federation/tests/query_plan/supergraphs/skip_type_explosion_early_if_unnecessary.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/skip_type_explosion_early_if_unnecessary.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 63eb1eb88aa472162170c24e74ca47c7c4ac1866 +# Composed from subgraphs with hash: 22a84f887ef58f251ff2c8f6439dcdfbdc1395fd schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -28,10 +28,19 @@ interface I s: S } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/subgraph_query_retains_the_query_variables_used_in_the_directives_applied_to_the_query.graphql b/apollo-federation/tests/query_plan/supergraphs/subgraph_query_retains_the_query_variables_used_in_the_directives_applied_to_the_query.graphql index 67fa096ee1..000717825c 100644 --- a/apollo-federation/tests/query_plan/supergraphs/subgraph_query_retains_the_query_variables_used_in_the_directives_applied_to_the_query.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/subgraph_query_retains_the_query_variables_used_in_the_directives_applied_to_the_query.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 64759e825a65c99c54fedcbf511cc7bf0735d4e2 +# Composed from subgraphs with hash: b577e09c4cb52223182c48413d146f984b798808 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -24,10 +24,19 @@ directive @link(url: String, as: String, for: link__Purpose, import: [link__Impo directive @withArgs(arg1: String) on QUERY +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/test_if_directives_at_the_operation_level_are_passed_down_to_subgraph_queries.graphql b/apollo-federation/tests/query_plan/supergraphs/test_if_directives_at_the_operation_level_are_passed_down_to_subgraph_queries.graphql index f2012f3f04..b7cd3853f8 100644 --- a/apollo-federation/tests/query_plan/supergraphs/test_if_directives_at_the_operation_level_are_passed_down_to_subgraph_queries.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/test_if_directives_at_the_operation_level_are_passed_down_to_subgraph_queries.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: a0524dbe1bbd3a7450a2e15f5c25c5cf2eed4242 +# Composed from subgraphs with hash: cc7760ea5772ca757685d5802613391331d0bb89 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query mutation: Mutation @@ -13,7 +13,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -37,10 +37,19 @@ type Foo baz: Int @join__field(graph: SUBGRAPHB) } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPHA @join__graph(name: "subgraphA", url: "none") SUBGRAPHB @join__graph(name: "subgraphB", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/test_if_directives_on_mutations_are_passed_down_to_subgraph_queries.graphql b/apollo-federation/tests/query_plan/supergraphs/test_if_directives_on_mutations_are_passed_down_to_subgraph_queries.graphql index f2012f3f04..b7cd3853f8 100644 --- a/apollo-federation/tests/query_plan/supergraphs/test_if_directives_on_mutations_are_passed_down_to_subgraph_queries.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/test_if_directives_on_mutations_are_passed_down_to_subgraph_queries.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: a0524dbe1bbd3a7450a2e15f5c25c5cf2eed4242 +# Composed from subgraphs with hash: cc7760ea5772ca757685d5802613391331d0bb89 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query mutation: Mutation @@ -13,7 +13,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -37,10 +37,19 @@ type Foo baz: Int @join__field(graph: SUBGRAPHB) } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPHA @join__graph(name: "subgraphA", url: "none") SUBGRAPHB @join__graph(name: "subgraphB", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/test_if_directives_with_arguments_applied_on_queries_are_ok.graphql b/apollo-federation/tests/query_plan/supergraphs/test_if_directives_with_arguments_applied_on_queries_are_ok.graphql index 5eb84bed66..088d93fd2e 100644 --- a/apollo-federation/tests/query_plan/supergraphs/test_if_directives_with_arguments_applied_on_queries_are_ok.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/test_if_directives_with_arguments_applied_on_queries_are_ok.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 5338f8c604ab7c2103bdf58ee6752a40d4b62ed8 +# Composed from subgraphs with hash: 835b813ecafe8b6b6bbffd9b802895d83cacac08 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -26,10 +26,19 @@ directive @noArgs on QUERY directive @withArgs(arg1: String) on QUERY +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/test_indirect_branch_merging_with_typename_sibling.graphql b/apollo-federation/tests/query_plan/supergraphs/test_indirect_branch_merging_with_typename_sibling.graphql index 462629b77a..2f2ab91aa6 100644 --- a/apollo-federation/tests/query_plan/supergraphs/test_indirect_branch_merging_with_typename_sibling.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/test_indirect_branch_merging_with_typename_sibling.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 9be0826e3b911556466c2c410f7df8b53c241774 +# Composed from subgraphs with hash: efc8cbf9c39df8acdc21d7cb3fb9e23700650a82 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -42,10 +42,19 @@ type B implements T f: Int! @join__field(graph: SUBGRAPH2) } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/test_interface_object_advance_with_non_collecting_and_type_preserving_transitions_ordering.graphql b/apollo-federation/tests/query_plan/supergraphs/test_interface_object_advance_with_non_collecting_and_type_preserving_transitions_ordering.graphql index da08220702..eb112a8850 100644 --- a/apollo-federation/tests/query_plan/supergraphs/test_interface_object_advance_with_non_collecting_and_type_preserving_transitions_ordering.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/test_interface_object_advance_with_non_collecting_and_type_preserving_transitions_ordering.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 415e22ad50245441330e67dc6637cf09714a4831 +# Composed from subgraphs with hash: 7c59bdaefc39d7e88a603f0560376a398e5b7e93 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -57,10 +57,19 @@ interface I data: String! @join__field(graph: Z) } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { S1 @join__graph(name: "S1", url: "none") S2 @join__graph(name: "S2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/test_merging_fetches_do_not_create_cycle_in_fetch_dependency_graph.graphql b/apollo-federation/tests/query_plan/supergraphs/test_merging_fetches_do_not_create_cycle_in_fetch_dependency_graph.graphql index 82e69229f1..c92362b1c7 100644 --- a/apollo-federation/tests/query_plan/supergraphs/test_merging_fetches_do_not_create_cycle_in_fetch_dependency_graph.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/test_merging_fetches_do_not_create_cycle_in_fetch_dependency_graph.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 0b567f1d7e0089a146e8499a2c5e412b78a98498 +# Composed from subgraphs with hash: 806d47884a3b16cd6552156d332df34cb74e0ffc schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { A @join__graph(name: "A", url: "none") B @join__graph(name: "B", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/test_merging_fetches_reset_cached_costs.graphql b/apollo-federation/tests/query_plan/supergraphs/test_merging_fetches_reset_cached_costs.graphql index 6b66fcbf6e..6f34ea9a77 100644 --- a/apollo-federation/tests/query_plan/supergraphs/test_merging_fetches_reset_cached_costs.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/test_merging_fetches_reset_cached_costs.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 7c07647747a84fd6c839bb603948dddcadf654fd +# Composed from subgraphs with hash: 0cd24ae6074a39994c982e5fa519acabfe2dcdac schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { A @join__graph(name: "A", url: "none") B @join__graph(name: "B", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/test_provides_edge_ordering.graphql b/apollo-federation/tests/query_plan/supergraphs/test_provides_edge_ordering.graphql index 6e2401f7d4..002b35a308 100644 --- a/apollo-federation/tests/query_plan/supergraphs/test_provides_edge_ordering.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/test_provides_edge_ordering.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: f5cb1210587d45fee11b9c57247d6c570d0ae7fd +# Composed from subgraphs with hash: 44564f95d87b3306e4c708b71f30f050c48d3a2d schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -31,10 +31,19 @@ type A data: String! @join__field(graph: SUBGRAPHX) @join__field(graph: SUBGRAPHY) } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPHQ @join__graph(name: "SubgraphQ", url: "none") SUBGRAPHX @join__graph(name: "SubgraphX", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/trying_to_use_defer_with_a_subcription_results_in_an_error.graphql b/apollo-federation/tests/query_plan/supergraphs/trying_to_use_defer_with_a_subcription_results_in_an_error.graphql index 1d901c0ee1..5958431c2c 100644 --- a/apollo-federation/tests/query_plan/supergraphs/trying_to_use_defer_with_a_subcription_results_in_an_error.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/trying_to_use_defer_with_a_subcription_results_in_an_error.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 4c8b155cb8183b493b5c2862a2bd4ce0261642f9 +# Composed from subgraphs with hash: ebc3c557daba5b588e6f31c98db4dea0296b99e7 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query subscription: Subscription @@ -11,7 +11,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -23,10 +23,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPHA @join__graph(name: "SubgraphA", url: "none") SUBGRAPHB @join__graph(name: "SubgraphB", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/union_interface_interaction.graphql b/apollo-federation/tests/query_plan/supergraphs/union_interface_interaction.graphql index 347f1bcfb8..d8b17e29b5 100644 --- a/apollo-federation/tests/query_plan/supergraphs/union_interface_interaction.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/union_interface_interaction.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 336400b353f835910c178a10eb77371f8700396b +# Composed from subgraphs with hash: a36c94877a2b170f973a35c58634ef4ee999c103 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -51,10 +51,19 @@ interface I v: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/union_interface_interaction_but_no_need_to_type_explode.graphql b/apollo-federation/tests/query_plan/supergraphs/union_interface_interaction_but_no_need_to_type_explode.graphql index 3dfc5d39b8..292658a75e 100644 --- a/apollo-federation/tests/query_plan/supergraphs/union_interface_interaction_but_no_need_to_type_explode.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/union_interface_interaction_but_no_need_to_type_explode.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 0457b8e67ae0ea99ead4c13318c4ac89e821aac3 +# Composed from subgraphs with hash: 82e74064026e626dde5798a7eaa1e6426c2c51d9 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -50,10 +50,19 @@ interface I v: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/union_union_interaction.graphql b/apollo-federation/tests/query_plan/supergraphs/union_union_interaction.graphql index bb7bf23e98..3e41a51d06 100644 --- a/apollo-federation/tests/query_plan/supergraphs/union_union_interaction.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/union_union_interaction.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 997336a5c7996069d8c10d0b9be46a72b46459c1 +# Composed from subgraphs with hash: 02b257e0662ad5b58d0147cb3c34c295418df23c schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -41,10 +41,19 @@ type C v: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/union_union_interaction_but_no_need_to_type_explode.graphql b/apollo-federation/tests/query_plan/supergraphs/union_union_interaction_but_no_need_to_type_explode.graphql index 3dd79adf66..aed475b293 100644 --- a/apollo-federation/tests/query_plan/supergraphs/union_union_interaction_but_no_need_to_type_explode.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/union_union_interaction_but_no_need_to_type_explode.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 241b1f7314833f7c2a97da8176e258c40322b0d7 +# Composed from subgraphs with hash: affd505df6fdd709ffe38651ddc517c8f33ec727 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -41,10 +41,19 @@ type C v: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/unnecessary_include_is_stripped_from_fragments.graphql b/apollo-federation/tests/query_plan/supergraphs/unnecessary_include_is_stripped_from_fragments.graphql index 33f5dd6f05..3c2493c9c8 100644 --- a/apollo-federation/tests/query_plan/supergraphs/unnecessary_include_is_stripped_from_fragments.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/unnecessary_include_is_stripped_from_fragments.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: e6c72fb53e93abe8f8aed4982aca6f6109fe1171 +# Composed from subgraphs with hash: 7267ff8701477b9b37e32de3063a369f4a7e2af3 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -37,10 +37,19 @@ type Foo bar: Bar } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/works_when_unset.graphql b/apollo-federation/tests/query_plan/supergraphs/works_when_unset.graphql index 42f3b4b125..a1f388ed61 100644 --- a/apollo-federation/tests/query_plan/supergraphs/works_when_unset.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/works_when_unset.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 91d4d0661d413b60ae2ed463c074c4180d7b849e +# Composed from subgraphs with hash: a9236eee956ed7fc219b2212696478159ced7eea schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") diff --git a/apollo-federation/tests/query_plan/supergraphs/works_with_key_chains.graphql b/apollo-federation/tests/query_plan/supergraphs/works_with_key_chains.graphql index 48816b3a72..3b8b99fd6d 100644 --- a/apollo-federation/tests/query_plan/supergraphs/works_with_key_chains.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/works_with_key_chains.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 4387e2f917c7748296b92799227648747e453bec +# Composed from subgraphs with hash: 2a34e202493c546249d10e9e361038512dd0e213 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -22,10 +22,19 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") From 1e5e703f1f2799e334066110ec82806932f5859a Mon Sep 17 00:00:00 2001 From: Duckki Oe Date: Wed, 6 Nov 2024 17:55:00 -0800 Subject: [PATCH 27/77] fix(federation): fixed a rebase error during flattening the input query (#6242) This fix handles a corner case where an inline fragment's selections are flattened into an empty selection set, but the fragment itself can't go away due to some reason (such as having a directive on it). --- apollo-federation/src/operation/simplify.rs | 32 ++++++--- .../query_plan/build_query_plan_tests.rs | 50 +++++++++++++ ...g_inline_fragment_due_to_directive.graphql | 71 +++++++++++++++++++ 3 files changed, 144 insertions(+), 9 deletions(-) create mode 100644 apollo-federation/tests/query_plan/supergraphs/rebase_non_intersecting_without_dropping_inline_fragment_due_to_directive.graphql diff --git a/apollo-federation/src/operation/simplify.rs b/apollo-federation/src/operation/simplify.rs index f7c339d210..a436c9f380 100644 --- a/apollo-federation/src/operation/simplify.rs +++ b/apollo-federation/src/operation/simplify.rs @@ -348,15 +348,29 @@ impl InlineFragmentSelection { } else { let rebased_inline_fragment = self.inline_fragment.rebase_on(parent_type, schema)?; let rebased_casted_type = rebased_inline_fragment.casted_type(); - let rebased_selection_set = - selection_set.rebase_on(&rebased_casted_type, named_fragments, schema)?; - Ok(Some( - Selection::InlineFragment(Arc::new(InlineFragmentSelection::new( - rebased_inline_fragment, - rebased_selection_set, - ))) - .into(), - )) + // Re-flatten with the rebased casted type, which could further flatten away. + let selection_set = selection_set.flatten_unnecessary_fragments( + &rebased_casted_type, + named_fragments, + schema, + )?; + if selection_set.is_empty() { + Ok(None) + } else { + // We need to rebase since the parent type for the selection set could be + // changed. + // Note: Rebasing after flattening, since rebasing before that can error out. + // Or, `flatten_unnecessary_fragments` could `rebase` at the same time. + let rebased_selection_set = + selection_set.rebase_on(&rebased_casted_type, named_fragments, schema)?; + Ok(Some( + Selection::InlineFragment(Arc::new(InlineFragmentSelection::new( + rebased_inline_fragment, + rebased_selection_set, + ))) + .into(), + )) + } } } } diff --git a/apollo-federation/tests/query_plan/build_query_plan_tests.rs b/apollo-federation/tests/query_plan/build_query_plan_tests.rs index 0e93f5a229..13ca9e52bd 100644 --- a/apollo-federation/tests/query_plan/build_query_plan_tests.rs +++ b/apollo-federation/tests/query_plan/build_query_plan_tests.rs @@ -1361,3 +1361,53 @@ fn condition_order_router799() { "### ); } + +#[test] +fn rebase_non_intersecting_without_dropping_inline_fragment_due_to_directive() { + let planner = planner!( + Subgraph1: r#" + type Query { + test: X + } + + interface I { + i: Int + } + + type X implements I { + i: Int + } + + type Y implements I { + i: Int + } + "#, + ); + assert_plan!( + &planner, + r#" + { + test { # type X + ... on I { # upcast to I + ... @skip(if: false) { # This fragment can't be dropped due to its directive. + ... on Y { # downcast to Y (non-intersecting) + i + } + } + } + } + } + "#, + @r###" + QueryPlan { + Fetch(service: "Subgraph1") { + { + test { + __typename @include(if: false) + } + } + }, + } + "### + ); +} diff --git a/apollo-federation/tests/query_plan/supergraphs/rebase_non_intersecting_without_dropping_inline_fragment_due_to_directive.graphql b/apollo-federation/tests/query_plan/supergraphs/rebase_non_intersecting_without_dropping_inline_fragment_due_to_directive.graphql new file mode 100644 index 0000000000..5e2b61e59e --- /dev/null +++ b/apollo-federation/tests/query_plan/supergraphs/rebase_non_intersecting_without_dropping_inline_fragment_due_to_directive.graphql @@ -0,0 +1,71 @@ +# Composed from subgraphs with hash: 8312d6d045a731f70fd2c9ced19d38ac8ae32ff5 +schema + @link(url: "https://specs.apollo.dev/link/v1.0") + @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) +{ + query: Query +} + +directive @join__directive(graphs: [join__Graph!], name: String!, args: join__DirectiveArguments) repeatable on SCHEMA | OBJECT | INTERFACE | FIELD_DEFINITION + +directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE + +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + +directive @join__graph(name: String!, url: String!) on ENUM_VALUE + +directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE + +directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true, isInterfaceObject: Boolean! = false) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + +directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on UNION + +directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA + +interface I + @join__type(graph: SUBGRAPH1) +{ + i: Int +} + +scalar join__DirectiveArguments + +scalar join__FieldSet + +enum join__Graph { + SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") +} + +scalar link__Import + +enum link__Purpose { + """ + `SECURITY` features provide metadata necessary to securely resolve fields. + """ + SECURITY + + """ + `EXECUTION` features provide metadata necessary for operation execution. + """ + EXECUTION +} + +type Query + @join__type(graph: SUBGRAPH1) +{ + test: X +} + +type X implements I + @join__implements(graph: SUBGRAPH1, interface: "I") + @join__type(graph: SUBGRAPH1) +{ + i: Int +} + +type Y implements I + @join__implements(graph: SUBGRAPH1, interface: "I") + @join__type(graph: SUBGRAPH1) +{ + i: Int +} From 0189a169ff61a520528fb91bee5bd43a560cf10f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e?= Date: Thu, 7 Nov 2024 10:16:58 +0000 Subject: [PATCH 28/77] chore(federation): add format-only error macro (#6236) --- apollo-federation/src/error/mod.rs | 49 +++++++++++++++- apollo-federation/src/operation/merging.rs | 14 ++--- apollo-federation/src/query_graph/mod.rs | 57 +++++++------------ .../src/query_plan/conditions.rs | 10 ++-- 4 files changed, 79 insertions(+), 51 deletions(-) diff --git a/apollo-federation/src/error/mod.rs b/apollo-federation/src/error/mod.rs index 97b7d2757d..cd163ecdab 100644 --- a/apollo-federation/src/error/mod.rs +++ b/apollo-federation/src/error/mod.rs @@ -13,11 +13,44 @@ use lazy_static::lazy_static; use crate::subgraph::spec::FederationSpecError; -/// Break out of the current function, returning an internal error. +/// Create an internal error. +/// +/// # Example +/// ```rust +/// use apollo_federation::internal_error; +/// use apollo_federation::error::FederationError; +/// # fn may_be_none() -> Option<()> { None } +/// +/// const NAME: &str = "the thing"; +/// let result: Result<(), FederationError> = may_be_none() +/// .ok_or_else(|| internal_error!("Expected {NAME} to be Some")); +/// ``` #[macro_export] macro_rules! internal_error { ( $( $arg:tt )+ ) => { - return Err($crate::error::FederationError::internal(format!( $( $arg )+ )).into()); + $crate::error::FederationError::internal(format!( $( $arg )+ )) + } +} + +/// Break out of the current function, returning an internal error. +/// +/// # Example +/// ```rust +/// use apollo_federation::bail; +/// use apollo_federation::error::FederationError; +/// # fn may_be_none() -> Option<()> { None } +/// +/// fn example() -> Result<(), FederationError> { +/// bail!("Something went horribly wrong"); +/// unreachable!() +/// } +/// # +/// # _ = example(); +/// ``` +#[macro_export] +macro_rules! bail { + ( $( $arg:tt )+ ) => { + return Err($crate::internal_error!( $( $arg )+ ).into()); } } @@ -26,6 +59,18 @@ macro_rules! internal_error { /// /// Treat this as an assertion. It must only be used for conditions that *should never happen* /// in normal operation. +/// +/// # Example +/// ```rust,no_run +/// use apollo_federation::ensure; +/// use apollo_federation::error::FederationError; +/// # fn may_be_none() -> Option<()> { None } +/// +/// fn example() -> Result<(), FederationError> { +/// ensure!(1 == 0, "Something went horribly wrong"); +/// unreachable!() +/// } +/// ``` #[macro_export] macro_rules! ensure { ( $expr:expr, $( $arg:tt )+ ) => { diff --git a/apollo-federation/src/operation/merging.rs b/apollo-federation/src/operation/merging.rs index c56ff5e66e..e7ebb8b63b 100644 --- a/apollo-federation/src/operation/merging.rs +++ b/apollo-federation/src/operation/merging.rs @@ -15,9 +15,9 @@ use super::NamedFragments; use super::Selection; use super::SelectionSet; use super::SelectionValue; +use crate::bail; use crate::ensure; use crate::error::FederationError; -use crate::internal_error; impl<'a> FieldSelectionValue<'a> { /// Merges the given field selections into this one. @@ -50,14 +50,14 @@ impl<'a> FieldSelectionValue<'a> { ); if self.get().selection_set.is_some() { let Some(other_selection_set) = &other.selection_set else { - internal_error!( + bail!( "Field \"{}\" has composite type but not a selection set", other_field.field_position, ); }; selection_sets.push(other_selection_set); } else if other.selection_set.is_some() { - internal_error!( + bail!( "Field \"{}\" has non-composite type but also has a selection set", other_field.field_position, ); @@ -187,7 +187,7 @@ impl SelectionSet { selection_map::Entry::Occupied(existing) => match existing.get() { Selection::Field(self_field_selection) => { let Selection::Field(other_field_selection) = other_selection else { - internal_error!( + bail!( "Field selection key for field \"{}\" references non-field selection", self_field_selection.field.field_position, ); @@ -201,7 +201,7 @@ impl SelectionSet { let Selection::FragmentSpread(other_fragment_spread_selection) = other_selection else { - internal_error!( + bail!( "Fragment spread selection key for fragment \"{}\" references non-field selection", self_fragment_spread_selection.spread.fragment_name, ); @@ -215,7 +215,7 @@ impl SelectionSet { let Selection::InlineFragment(other_inline_fragment_selection) = other_selection else { - internal_error!( + bail!( "Inline fragment selection key under parent type \"{}\" {}references non-field selection", self_inline_fragment_selection.inline_fragment.parent_type_position, self_inline_fragment_selection.inline_fragment.type_condition_position.clone() @@ -368,7 +368,7 @@ pub(crate) fn merge_selection_sets( mut selection_sets: Vec, ) -> Result { let Some((first, remainder)) = selection_sets.split_first_mut() else { - internal_error!("merge_selection_sets(): must have at least one selection set"); + bail!("merge_selection_sets(): must have at least one selection set"); }; first.merge_into(remainder.iter())?; diff --git a/apollo-federation/src/query_graph/mod.rs b/apollo-federation/src/query_graph/mod.rs index 344d9dc01d..736f7af567 100644 --- a/apollo-federation/src/query_graph/mod.rs +++ b/apollo-federation/src/query_graph/mod.rs @@ -16,6 +16,7 @@ use petgraph::Direction; use crate::error::FederationError; use crate::error::SingleFederationError; +use crate::internal_error; use crate::operation::Field; use crate::operation::InlineFragment; use crate::operation::SelectionSet; @@ -368,39 +369,27 @@ impl QueryGraph { } pub(crate) fn node_weight(&self, node: NodeIndex) -> Result<&QueryGraphNode, FederationError> { - self.graph.node_weight(node).ok_or_else(|| { - SingleFederationError::Internal { - message: "Node unexpectedly missing".to_owned(), - } - .into() - }) + self.graph + .node_weight(node) + .ok_or_else(|| internal_error!("Node unexpectedly missing")) } fn node_weight_mut(&mut self, node: NodeIndex) -> Result<&mut QueryGraphNode, FederationError> { - self.graph.node_weight_mut(node).ok_or_else(|| { - SingleFederationError::Internal { - message: "Node unexpectedly missing".to_owned(), - } - .into() - }) + self.graph + .node_weight_mut(node) + .ok_or_else(|| internal_error!("Node unexpectedly missing")) } pub(crate) fn edge_weight(&self, edge: EdgeIndex) -> Result<&QueryGraphEdge, FederationError> { - self.graph.edge_weight(edge).ok_or_else(|| { - SingleFederationError::Internal { - message: "Edge unexpectedly missing".to_owned(), - } - .into() - }) + self.graph + .edge_weight(edge) + .ok_or_else(|| internal_error!("Edge unexpectedly missing")) } fn edge_weight_mut(&mut self, edge: EdgeIndex) -> Result<&mut QueryGraphEdge, FederationError> { - self.graph.edge_weight_mut(edge).ok_or_else(|| { - SingleFederationError::Internal { - message: "Edge unexpectedly missing".to_owned(), - } - .into() - }) + self.graph + .edge_weight_mut(edge) + .ok_or_else(|| internal_error!("Edge unexpectedly missing")) } pub(crate) fn edge_head_weight( @@ -415,12 +404,9 @@ impl QueryGraph { &self, edge: EdgeIndex, ) -> Result<(NodeIndex, NodeIndex), FederationError> { - self.graph.edge_endpoints(edge).ok_or_else(|| { - SingleFederationError::Internal { - message: "Edge unexpectedly missing".to_owned(), - } - .into() - }) + self.graph + .edge_endpoints(edge) + .ok_or_else(|| internal_error!("Edge unexpectedly missing")) } fn schema(&self) -> Result<&ValidFederationSchema, FederationError> { @@ -431,12 +417,9 @@ impl QueryGraph { &self, source: &str, ) -> Result<&ValidFederationSchema, FederationError> { - self.sources.get(source).ok_or_else(|| { - SingleFederationError::Internal { - message: "Schema unexpectedly missing".to_owned(), - } - .into() - }) + self.sources + .get(source) + .ok_or_else(|| internal_error!(r#"Schema for "{source}" unexpectedly missing"#)) } pub(crate) fn subgraph_schemas(&self) -> &IndexMap, ValidFederationSchema> { @@ -454,7 +437,7 @@ impl QueryGraph { ) -> Result<&IndexSet, FederationError> { self.types_to_nodes()? .get(name) - .ok_or_else(|| FederationError::internal("No nodes unexpectedly found for type")) + .ok_or_else(|| internal_error!("No nodes unexpectedly found for type")) } pub(crate) fn types_to_nodes( diff --git a/apollo-federation/src/query_plan/conditions.rs b/apollo-federation/src/query_plan/conditions.rs index cf248c8b61..f202fd4058 100644 --- a/apollo-federation/src/query_plan/conditions.rs +++ b/apollo-federation/src/query_plan/conditions.rs @@ -8,8 +8,8 @@ use apollo_compiler::Node; use indexmap::map::Entry; use serde::Serialize; +use crate::bail; use crate::error::FederationError; -use crate::internal_error; use crate::operation::DirectiveList; use crate::operation::NamedFragments; use crate::operation::Selection; @@ -122,7 +122,7 @@ impl Conditions { if let Some(skip) = directives.get("skip") { let Some(value) = skip.specified_argument_by_name("if") else { - internal_error!("missing @skip(if:) argument"); + bail!("missing @skip(if:) argument"); }; match value.as_ref() { @@ -134,14 +134,14 @@ impl Conditions { variables.insert(name.clone(), ConditionKind::Skip); } _ => { - internal_error!("expected boolean or variable `if` argument, got {value}"); + bail!("expected boolean or variable `if` argument, got {value}"); } } } if let Some(include) = directives.get("include") { let Some(value) = include.specified_argument_by_name("if") else { - internal_error!("missing @include(if:) argument"); + bail!("missing @include(if:) argument"); }; match value.as_ref() { @@ -159,7 +159,7 @@ impl Conditions { } } _ => { - internal_error!("expected boolean or variable `if` argument, got {value}"); + bail!("expected boolean or variable `if` argument, got {value}"); } } } From b09bda04aece852b44f7bb8ad9d9d111f8abd133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e?= Date: Fri, 8 Nov 2024 12:13:46 +0000 Subject: [PATCH 29/77] fix(federation): recompose test supergraph (#6243) --- ...pping_inline_fragment_due_to_directive.graphql | 15 ++++++++++++--- .../src/plugins/telemetry/formatters/json.rs | 4 ++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/apollo-federation/tests/query_plan/supergraphs/rebase_non_intersecting_without_dropping_inline_fragment_due_to_directive.graphql b/apollo-federation/tests/query_plan/supergraphs/rebase_non_intersecting_without_dropping_inline_fragment_due_to_directive.graphql index 5e2b61e59e..55fea881e2 100644 --- a/apollo-federation/tests/query_plan/supergraphs/rebase_non_intersecting_without_dropping_inline_fragment_due_to_directive.graphql +++ b/apollo-federation/tests/query_plan/supergraphs/rebase_non_intersecting_without_dropping_inline_fragment_due_to_directive.graphql @@ -1,7 +1,7 @@ -# Composed from subgraphs with hash: 8312d6d045a731f70fd2c9ced19d38ac8ae32ff5 +# Composed from subgraphs with hash: 9f65288304601b6cf28091f55f98c58ca3c82972 schema @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { query: Query } @@ -10,7 +10,7 @@ directive @join__directive(graphs: [join__Graph!], name: String!, args: join__Di directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION directive @join__graph(name: String!, url: String!) on ENUM_VALUE @@ -28,10 +28,19 @@ interface I i: Int } +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + scalar join__DirectiveArguments scalar join__FieldSet +scalar join__FieldValue + enum join__Graph { SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") } diff --git a/apollo-router/src/plugins/telemetry/formatters/json.rs b/apollo-router/src/plugins/telemetry/formatters/json.rs index 8f6551ce14..7bb94bfebd 100644 --- a/apollo-router/src/plugins/telemetry/formatters/json.rs +++ b/apollo-router/src/plugins/telemetry/formatters/json.rs @@ -500,7 +500,7 @@ mod test { .or_else(|| ctx.lookup_current()) .expect("current span expected"); let extracted = extract_dd_trace_id(¤t_span); - assert_eq!(extracted, Some("1234".to_string())); + assert_eq!(extracted, Some("1234".to_string()), "should have trace id"); } } @@ -535,7 +535,7 @@ mod test { } #[test] - #[should_panic] + #[should_panic(expected = "should have trace id")] fn test_missing_dd_attribute() { subscriber::with_default( Registry::default() From fd955e30e4b43540fb6992f7c271a8778a3817cb Mon Sep 17 00:00:00 2001 From: Edward Huang Date: Fri, 8 Nov 2024 13:42:39 -0800 Subject: [PATCH 30/77] reorg dev docs for new docs IA (#6248) --- docs/shared/native-plugin-notice.mdx | 2 +- docs/source/config.json | 128 +----- .../experimental_query_planner_mode.mdx | 34 -- .../build-run-queries.mdx | 15 - .../images/cloud-dedicated/add-a-subgraph.jpg | Bin 0 -> 469348 bytes .../cloud-dedicated/create-new-graph.jpg | Bin 0 -> 266839 bytes .../create-resource-share-final.jpg | Bin 0 -> 33250 bytes .../delete-network-associations.jpg | Bin 0 -> 95258 bytes .../cloud-dedicated/delete-resource-share.jpg | Bin 0 -> 25589 bytes .../cloud-dedicated/graphos-service.jpg | Bin 0 -> 84005 bytes .../images/cloud-dedicated/http-listener.jpg | Bin 0 -> 69783 bytes .../images/cloud-dedicated/insights-page.jpg | Bin 0 -> 529227 bytes .../cloud-dedicated/manage-capacity.jpg | Bin 0 -> 200950 bytes .../cloud-dedicated/managed-permissions.jpg | Bin 0 -> 79395 bytes .../cloud-dedicated/register-targets.jpg | Bin 0 -> 125281 bytes .../images/cloud-dedicated/request-rate.jpg | Bin 0 -> 195784 bytes .../cloud-dedicated/resource-principal.jpg | Bin 0 -> 76432 bytes .../cloud-dedicated/resource-selection.jpg | Bin 0 -> 74443 bytes .../resource-share-summary.jpg | Bin 0 -> 42242 bytes .../cloud-dedicated/service-identifiers.jpg | Bin 0 -> 96953 bytes .../images/cloud-dedicated/service-rules.jpg | Bin 0 -> 67029 bytes .../target-group-configuration.jpg | Bin 0 -> 151317 bytes .../vpc-lattice-access-logs.png | Bin 0 -> 63202 bytes .../cloud-dedicated/vpc-lattice-metrics.png | Bin 0 -> 105477 bytes .../cloud-dedicated/vpc-lattice-routing.png | Bin 0 -> 141823 bytes docs/source/images/get-started/qp-dark.svg | 24 ++ docs/source/images/get-started/qp.svg | 24 ++ .../get-started/super-routing-1-dark.svg | 55 +++ .../images/get-started/super-routing-1.svg | 65 +++ .../get-started/super-routing-2-dark.svg | 59 +++ .../images/get-started/super-routing-2.svg | 69 ++++ .../get-started/super-routing-3-dark.svg | 67 ++++ .../images/get-started/super-routing-3.svg | 67 ++++ docs/source/images/initiating-endpoint.jpg | Bin 0 -> 45232 bytes .../router/cloud-router-configuration.jpg | Bin 0 -> 358832 bytes .../images/router/cloud-router-details.jpg | Bin 0 -> 81251 bytes .../images/router/cloud-router-region-ord.jpg | Bin 0 -> 74181 bytes docs/source/images/router/router-endpoint.jpg | Bin 0 -> 108435 bytes docs/source/index.mdx | 76 ---- docs/source/privacy.mdx | 31 -- .../graphos-features.mdx} | 70 ++-- .../migration/from-gateway.mdx} | 26 +- .../migration/from-router-version-0.x.mdx} | 20 +- .../router/configuration.mdx} | 209 ++++++---- docs/source/{ => reference/router}/errors.mdx | 11 +- .../router}/federation-version-support.mdx | 0 .../router/rhai.mdx} | 8 +- .../router/self-hosted-install.mdx} | 6 +- .../telemetry/instrumentation/conditions.mdx | 6 +- .../telemetry/instrumentation/events.mdx | 16 +- .../telemetry/instrumentation/instruments.mdx | 19 +- .../telemetry/instrumentation/selectors.mdx | 4 +- .../telemetry/instrumentation/spans.mdx | 12 +- .../instrumentation/standard-attributes.mdx | 14 +- .../instrumentation/standard-instruments.mdx | 4 +- .../telemetry/log-exporters}/overview.mdx | 2 +- .../telemetry/log-exporters}/stdout.mdx | 6 +- .../telemetry/metrics-exporters}/datadog.mdx | 6 +- .../metrics-exporters}/dynatrace.mdx | 6 +- .../metrics-exporters}/new-relic.mdx | 6 +- .../telemetry/metrics-exporters}/otlp.mdx | 8 +- .../telemetry/metrics-exporters}/overview.mdx | 22 +- .../metrics-exporters}/prometheus.mdx | 4 +- .../telemetry/trace-exporters}/datadog.mdx | 4 +- .../telemetry/trace-exporters}/dynatrace.mdx | 6 +- .../telemetry/trace-exporters}/jaeger.mdx | 4 +- .../telemetry/trace-exporters}/new-relic.mdx | 6 +- .../telemetry/trace-exporters}/otlp.mdx | 10 +- .../telemetry/trace-exporters}/overview.mdx | 20 +- .../telemetry/trace-exporters}/zipkin.mdx | 2 +- docs/source/routing/about-router.mdx | 150 +++++++ docs/source/routing/cloud/aws-migration.mdx | 159 ++++++++ docs/source/routing/cloud/configuration.mdx | 373 ++++++++++++++++++ docs/source/routing/cloud/custom-domains.mdx | 72 ++++ .../routing/cloud/dedicated-quickstart.mdx | 138 +++++++ docs/source/routing/cloud/dedicated.mdx | 52 +++ docs/source/routing/cloud/index.mdx | 166 ++++++++ .../routing/cloud/lattice-configuration.mdx | 348 ++++++++++++++++ .../routing/cloud/lattice-management.mdx | 181 +++++++++ .../routing/cloud/lattice-troubleshooting.mdx | 135 +++++++ .../routing/cloud/migrate-to-dedicated.mdx | 54 +++ .../source/routing/cloud/secure-subgraphs.mdx | 89 +++++ docs/source/routing/cloud/serverless.mdx | 50 +++ docs/source/routing/cloud/subscriptions.mdx | 219 ++++++++++ .../source/routing/cloud/throughput-guide.mdx | 157 ++++++++ docs/source/routing/configure-your-router.mdx | 103 +++++ .../customization}/coprocessor.mdx | 38 +- .../customization}/custom-binary.mdx | 6 +- .../customization/native-plugins.mdx} | 24 +- .../customization}/overview.mdx | 12 +- .../customization}/rhai.mdx | 12 +- .../graphos-reporting.mdx} | 114 +++--- .../guides/request-format.mdx} | 26 +- .../header-propagation.mdx | 6 +- .../observability}/client-awareness.mdx | 2 +- .../observability/client-id-enforcement.mdx | 143 +++++++ .../debugging-subgraph-requests.mdx | 88 +++++ docs/source/routing/observability/index.mdx | 67 ++++ .../otel-traces-to-prometheus.mdx | 106 +++++ .../subgraph-error-inclusion.mdx | 6 +- .../observability/telemetry.mdx} | 24 +- .../operations/defer.mdx} | 121 +++++- .../operations/file-upload.mdx} | 2 +- docs/source/routing/operations/index.mdx | 11 + .../operations/subscriptions/api-gateway.mdx | 100 +++++ .../subscriptions/callback-protocol.mdx} | 2 +- .../operations/subscriptions/index.mdx} | 24 +- .../subscriptions/multipart-protocol.mdx} | 2 +- .../performance/caching/distributed.mdx} | 38 +- .../performance/caching/entity.mdx} | 14 +- .../performance/caching/in-memory.mdx} | 16 +- .../routing/performance/caching/index.mdx | 16 + .../performance}/query-batching.mdx | 2 +- .../performance/query-planner-pools.mdx | 34 ++ .../performance}/traffic-shaping.mdx | 25 +- .../query-planning/native-query-planner.mdx | 79 ++++ .../routing/router-api-gateway-comparison.mdx | 115 ++++++ .../security}/authorization.mdx | 37 +- .../security}/cors.mdx | 2 +- .../security}/csrf.mdx | 8 +- .../security}/demand-control.mdx | 14 +- docs/source/routing/security/index.mdx | 21 + .../security/jwt.mdx} | 46 +-- .../security}/persisted-queries.mdx | 16 +- .../security/request-limits.mdx} | 124 ++++-- .../security/router-authentication.mdx | 214 ++++++++++ .../security/subgraph-authentication.mdx} | 6 - docs/source/routing/security/tls.mdx | 135 +++++++ .../self-hosted}/containerization/docker.mdx | 8 +- .../self-hosted/containerization/index.mdx} | 6 +- .../containerization/kubernetes.mdx | 28 +- .../containerization/optimize-build.mdx | 58 +++ .../self-hosted}/health-checks.mdx | 2 +- docs/source/routing/self-hosted/index.mdx | 49 +++ .../self-hosted/resource-estimator.mdx | 28 ++ .../self-hosted/resource-management.mdx | 61 +++ 136 files changed, 4942 insertions(+), 895 deletions(-) delete mode 100644 docs/source/configuration/experimental_query_planner_mode.mdx delete mode 100644 docs/source/executing-operations/build-run-queries.mdx create mode 100644 docs/source/images/cloud-dedicated/add-a-subgraph.jpg create mode 100644 docs/source/images/cloud-dedicated/create-new-graph.jpg create mode 100644 docs/source/images/cloud-dedicated/create-resource-share-final.jpg create mode 100644 docs/source/images/cloud-dedicated/delete-network-associations.jpg create mode 100644 docs/source/images/cloud-dedicated/delete-resource-share.jpg create mode 100644 docs/source/images/cloud-dedicated/graphos-service.jpg create mode 100644 docs/source/images/cloud-dedicated/http-listener.jpg create mode 100644 docs/source/images/cloud-dedicated/insights-page.jpg create mode 100644 docs/source/images/cloud-dedicated/manage-capacity.jpg create mode 100644 docs/source/images/cloud-dedicated/managed-permissions.jpg create mode 100644 docs/source/images/cloud-dedicated/register-targets.jpg create mode 100644 docs/source/images/cloud-dedicated/request-rate.jpg create mode 100644 docs/source/images/cloud-dedicated/resource-principal.jpg create mode 100644 docs/source/images/cloud-dedicated/resource-selection.jpg create mode 100644 docs/source/images/cloud-dedicated/resource-share-summary.jpg create mode 100644 docs/source/images/cloud-dedicated/service-identifiers.jpg create mode 100644 docs/source/images/cloud-dedicated/service-rules.jpg create mode 100644 docs/source/images/cloud-dedicated/target-group-configuration.jpg create mode 100644 docs/source/images/cloud-dedicated/vpc-lattice-access-logs.png create mode 100644 docs/source/images/cloud-dedicated/vpc-lattice-metrics.png create mode 100644 docs/source/images/cloud-dedicated/vpc-lattice-routing.png create mode 100644 docs/source/images/get-started/qp-dark.svg create mode 100644 docs/source/images/get-started/qp.svg create mode 100644 docs/source/images/get-started/super-routing-1-dark.svg create mode 100644 docs/source/images/get-started/super-routing-1.svg create mode 100644 docs/source/images/get-started/super-routing-2-dark.svg create mode 100644 docs/source/images/get-started/super-routing-2.svg create mode 100644 docs/source/images/get-started/super-routing-3-dark.svg create mode 100644 docs/source/images/get-started/super-routing-3.svg create mode 100644 docs/source/images/initiating-endpoint.jpg create mode 100644 docs/source/images/router/cloud-router-configuration.jpg create mode 100644 docs/source/images/router/cloud-router-details.jpg create mode 100644 docs/source/images/router/cloud-router-region-ord.jpg create mode 100644 docs/source/images/router/router-endpoint.jpg delete mode 100644 docs/source/index.mdx delete mode 100644 docs/source/privacy.mdx rename docs/source/{enterprise-features.mdx => reference/graphos-features.mdx} (67%) rename docs/source/{migrating-from-gateway.mdx => reference/migration/from-gateway.mdx} (85%) rename docs/source/{migrating-from-version-0.x.mdx => reference/migration/from-router-version-0.x.mdx} (88%) rename docs/source/{configuration/overview.mdx => reference/router/configuration.mdx} (85%) rename docs/source/{ => reference/router}/errors.mdx (87%) rename docs/source/{ => reference/router}/federation-version-support.mdx (100%) rename docs/source/{customizations/rhai-api.mdx => reference/router/rhai.mdx} (97%) rename docs/source/{quickstart.mdx => reference/router/self-hosted-install.mdx} (97%) rename docs/source/{configuration => reference/router}/telemetry/instrumentation/conditions.mdx (89%) rename docs/source/{configuration => reference/router}/telemetry/instrumentation/events.mdx (86%) rename docs/source/{configuration => reference/router}/telemetry/instrumentation/instruments.mdx (90%) rename docs/source/{configuration => reference/router}/telemetry/instrumentation/selectors.mdx (96%) rename docs/source/{configuration => reference/router}/telemetry/instrumentation/spans.mdx (87%) rename docs/source/{configuration => reference/router}/telemetry/instrumentation/standard-attributes.mdx (89%) rename docs/source/{configuration => reference/router}/telemetry/instrumentation/standard-instruments.mdx (97%) rename docs/source/{configuration/telemetry/exporters/logging => reference/router/telemetry/log-exporters}/overview.mdx (97%) rename docs/source/{configuration/telemetry/exporters/logging => reference/router/telemetry/log-exporters}/stdout.mdx (97%) rename docs/source/{configuration/telemetry/exporters/metrics => reference/router/telemetry/metrics-exporters}/datadog.mdx (74%) rename docs/source/{configuration/telemetry/exporters/metrics => reference/router/telemetry/metrics-exporters}/dynatrace.mdx (85%) rename docs/source/{configuration/telemetry/exporters/metrics => reference/router/telemetry/metrics-exporters}/new-relic.mdx (71%) rename docs/source/{configuration/telemetry/exporters/metrics => reference/router/telemetry/metrics-exporters}/otlp.mdx (92%) rename docs/source/{configuration/telemetry/exporters/metrics => reference/router/telemetry/metrics-exporters}/overview.mdx (89%) rename docs/source/{configuration/telemetry/exporters/metrics => reference/router/telemetry/metrics-exporters}/prometheus.mdx (94%) rename docs/source/{configuration/telemetry/exporters/tracing => reference/router/telemetry/trace-exporters}/datadog.mdx (97%) rename docs/source/{configuration/telemetry/exporters/tracing => reference/router/telemetry/trace-exporters}/dynatrace.mdx (81%) rename docs/source/{configuration/telemetry/exporters/tracing => reference/router/telemetry/trace-exporters}/jaeger.mdx (95%) rename docs/source/{configuration/telemetry/exporters/tracing => reference/router/telemetry/trace-exporters}/new-relic.mdx (64%) rename docs/source/{configuration/telemetry/exporters/tracing => reference/router/telemetry/trace-exporters}/otlp.mdx (90%) rename docs/source/{configuration/telemetry/exporters/tracing => reference/router/telemetry/trace-exporters}/overview.mdx (90%) rename docs/source/{configuration/telemetry/exporters/tracing => reference/router/telemetry/trace-exporters}/zipkin.mdx (96%) create mode 100644 docs/source/routing/about-router.mdx create mode 100644 docs/source/routing/cloud/aws-migration.mdx create mode 100644 docs/source/routing/cloud/configuration.mdx create mode 100644 docs/source/routing/cloud/custom-domains.mdx create mode 100644 docs/source/routing/cloud/dedicated-quickstart.mdx create mode 100644 docs/source/routing/cloud/dedicated.mdx create mode 100644 docs/source/routing/cloud/index.mdx create mode 100644 docs/source/routing/cloud/lattice-configuration.mdx create mode 100644 docs/source/routing/cloud/lattice-management.mdx create mode 100644 docs/source/routing/cloud/lattice-troubleshooting.mdx create mode 100644 docs/source/routing/cloud/migrate-to-dedicated.mdx create mode 100644 docs/source/routing/cloud/secure-subgraphs.mdx create mode 100644 docs/source/routing/cloud/serverless.mdx create mode 100644 docs/source/routing/cloud/subscriptions.mdx create mode 100644 docs/source/routing/cloud/throughput-guide.mdx create mode 100644 docs/source/routing/configure-your-router.mdx rename docs/source/{customizations => routing/customization}/coprocessor.mdx (93%) rename docs/source/{customizations => routing/customization}/custom-binary.mdx (96%) rename docs/source/{customizations/native.mdx => routing/customization/native-plugins.mdx} (90%) rename docs/source/{customizations => routing/customization}/overview.mdx (93%) rename docs/source/{customizations => routing/customization}/rhai.mdx (97%) rename docs/source/{configuration/telemetry/apollo-telemetry.mdx => routing/graphos-reporting.mdx} (74%) rename docs/source/{executing-operations/requests.mdx => routing/guides/request-format.mdx} (51%) rename docs/source/{configuration => routing}/header-propagation.mdx (97%) rename docs/source/{managed-federation => routing/observability}/client-awareness.mdx (96%) create mode 100644 docs/source/routing/observability/client-id-enforcement.mdx create mode 100644 docs/source/routing/observability/debugging-subgraph-requests.mdx create mode 100644 docs/source/routing/observability/index.mdx create mode 100644 docs/source/routing/observability/otel-traces-to-prometheus.mdx rename docs/source/{configuration => routing/observability}/subgraph-error-inclusion.mdx (84%) rename docs/source/{configuration/telemetry/overview.mdx => routing/observability/telemetry.mdx} (76%) rename docs/source/{executing-operations/defer-support.mdx => routing/operations/defer.mdx} (69%) rename docs/source/{executing-operations/file-uploads.mdx => routing/operations/file-upload.mdx} (99%) create mode 100644 docs/source/routing/operations/index.mdx create mode 100644 docs/source/routing/operations/subscriptions/api-gateway.mdx rename docs/source/{executing-operations/subscription-callback-protocol.mdx => routing/operations/subscriptions/callback-protocol.mdx} (98%) rename docs/source/{executing-operations/subscription-support.mdx => routing/operations/subscriptions/index.mdx} (95%) rename docs/source/{executing-operations/subscription-multipart-protocol.mdx => routing/operations/subscriptions/multipart-protocol.mdx} (98%) rename docs/source/{configuration/distributed-caching.mdx => routing/performance/caching/distributed.mdx} (83%) rename docs/source/{configuration/entity-caching.mdx => routing/performance/caching/entity.mdx} (94%) rename docs/source/{configuration/in-memory-caching.mdx => routing/performance/caching/in-memory.mdx} (87%) create mode 100644 docs/source/routing/performance/caching/index.mdx rename docs/source/{executing-operations => routing/performance}/query-batching.mdx (97%) create mode 100644 docs/source/routing/performance/query-planner-pools.mdx rename docs/source/{configuration => routing/performance}/traffic-shaping.mdx (89%) create mode 100644 docs/source/routing/query-planning/native-query-planner.mdx create mode 100644 docs/source/routing/router-api-gateway-comparison.mdx rename docs/source/{configuration => routing/security}/authorization.mdx (88%) rename docs/source/{configuration => routing/security}/cors.mdx (98%) rename docs/source/{configuration => routing/security}/csrf.mdx (95%) rename docs/source/{executing-operations => routing/security}/demand-control.mdx (97%) create mode 100644 docs/source/routing/security/index.mdx rename docs/source/{configuration/authn-jwt.mdx => routing/security/jwt.mdx} (88%) rename docs/source/{configuration => routing/security}/persisted-queries.mdx (69%) rename docs/source/{configuration/operation-limits.mdx => routing/security/request-limits.mdx} (60%) create mode 100644 docs/source/routing/security/router-authentication.mdx rename docs/source/{configuration/authn-subgraph.mdx => routing/security/subgraph-authentication.mdx} (94%) create mode 100644 docs/source/routing/security/tls.mdx rename docs/source/{ => routing/self-hosted}/containerization/docker.mdx (94%) rename docs/source/{containerization/overview.mdx => routing/self-hosted/containerization/index.mdx} (90%) rename docs/source/{ => routing/self-hosted}/containerization/kubernetes.mdx (87%) create mode 100644 docs/source/routing/self-hosted/containerization/optimize-build.mdx rename docs/source/{configuration => routing/self-hosted}/health-checks.mdx (97%) create mode 100644 docs/source/routing/self-hosted/index.mdx create mode 100644 docs/source/routing/self-hosted/resource-estimator.mdx create mode 100644 docs/source/routing/self-hosted/resource-management.mdx diff --git a/docs/shared/native-plugin-notice.mdx b/docs/shared/native-plugin-notice.mdx index 7d957b0d31..be0bcf185b 100644 --- a/docs/shared/native-plugin-notice.mdx +++ b/docs/shared/native-plugin-notice.mdx @@ -3,6 +3,6 @@ - Native plugins require familiarity with programming in Rust. - Native plugins require compiling a custom router binary from source, which can introduce unexpected behavior in your router that's difficult to diagnose and support. -Instead, for most router customizations, Apollo recommends creating either a [Rhai script](https://www.apollographql.com/docs/router/customizations/rhai/) or an [external coprocessor](https://www.apollographql.com/docs/router/customizations/coprocessor). Both of these customizations are supported by Apollo and provide strong separation of concerns and fault isolation. +Instead, for most router customizations, Apollo recommends creating either a [Rhai script](https://www.apollographql.com/docs/graphos/routing/customization/rhai/) or an [external coprocessor](https://www.apollographql.com/docs/router/customizations/coprocessor). Both of these customizations are supported by Apollo and provide strong separation of concerns and fault isolation. If you must create a native plugin, please [open a GitHub issue](https://github.com/apollographql/router/issues), and Apollo can investigate adding the custom capability to the stock router binary. diff --git a/docs/source/config.json b/docs/source/config.json index c0d464777e..8e481a369b 100644 --- a/docs/source/config.json +++ b/docs/source/config.json @@ -2,130 +2,16 @@ "title": "Self-Hosted Router", "algoliaFilters": ["docset:router"], "sidebar": { - "Introduction": "/", - "Quickstart": "/quickstart", - "Moving from @apollo/gateway": "/migrating-from-gateway", - "Federation Version Support": "/federation-version-support", - "Enterprise Features": ["/enterprise-features", ["enterprise"]], - "Configuring the Router": { - "Overview": "/configuration/overview", - "Caching": { - "In-Memory Caching": "/configuration/in-memory-caching", - "Distributed Caching": ["/configuration/distributed-caching", ["enterprise"]], - "Entity Caching": ["/configuration/entity-caching", ["enterprise", "preview"]] - }, - "Debugging": { - "Errors": "/errors", - "Telemetry": "/configuration/telemetry/overview", - "Subgraph Error Inclusion": "/configuration/subgraph-error-inclusion" - }, - "Networking": { - "Header Propagation": "/configuration/header-propagation", - "Traffic Shaping": "/configuration/traffic-shaping" - }, - "Security": { - "CORS": "/configuration/cors", - "CSRF Prevention": "/configuration/csrf", - "JWT Authentication": ["/configuration/authn-jwt", ["enterprise"]], - "Authorization": ["/configuration/authorization", ["enterprise"]], - "Subgraph Authentication": "/configuration/authn-subgraph", - "Operation Limits": [ - "/configuration/operation-limits", - [ - "enterprise" - ] - ], - "Safelisting with Persisted Queries": [ - "/configuration/persisted-queries", - [ - "enterprise" - ] - ], - "Demand Control" : [ - "/executing-operations/demand-control", - [ - "enterprise" - ] - ], - "Privacy and Data Collection": "/privacy" - } - }, - "Executing Operations": { - "Build and Run Queries": "/executing-operations/build-run-queries", - "@defer Support": "/executing-operations/defer-support", - "Request Format": "/executing-operations/requests", - "Query Batching": [ - "/executing-operations/query-batching", - [ - "enterprise" - ] - ], - "GraphQL Subscriptions": { - "Subscriptions Setup": ["/executing-operations/subscription-support", ["enterprise"]], - "Subgraph Protocol: HTTP Callback": [ - "/executing-operations/subscription-callback-protocol", - ["enterprise", "preview"] - ], - "Client Protocol: HTTP Multipart": ["/executing-operations/subscription-multipart-protocol", ["enterprise"]] - } + "Routing": { + "About Router": "/routing/about-router" }, - "Telemetry and Monitoring": { - "Overview": "/configuration/telemetry/overview", - "GraphOS Reporting": "/configuration/telemetry/apollo-telemetry", - "Client Awareness": "/managed-federation/client-awareness", - "Log Exporters": { - "Configuration": "/configuration/telemetry/exporters/logging/overview", - "Stdout": "/configuration/telemetry/exporters/logging/stdout" + "Reference": { + "Migration": { + "From Gateway": "/reference/migration/from-gateway" }, - "Metrics Exporters": { - "Configuration": "/configuration/telemetry/exporters/metrics/overview", - "Datadog": "/configuration/telemetry/exporters/metrics/datadog", - "Dynatrace": "/configuration/telemetry/exporters/metrics/dynatrace", - "New Relic": "/configuration/telemetry/exporters/metrics/new-relic", - "OTLP": "/configuration/telemetry/exporters/metrics/otlp", - "Prometheus": "/configuration/telemetry/exporters/metrics/prometheus" - }, - "Trace exporters": { - "Configuration": "/configuration/telemetry/exporters/tracing/overview", - "Datadog": "/configuration/telemetry/exporters/tracing/datadog", - "Dynatrace": "/configuration/telemetry/exporters/tracing/dynatrace", - "Jaeger": "/configuration/telemetry/exporters/tracing/jaeger", - "New Relic": "/configuration/telemetry/exporters/tracing/new-relic", - "OTLP": "/configuration/telemetry/exporters/tracing/otlp", - "Zipkin": "/configuration/telemetry/exporters/tracing/zipkin" - }, - "Instrumentation": { - "Instruments": "/configuration/telemetry/instrumentation/instruments", - "Events": "/configuration/telemetry/instrumentation/events", - "Conditions": "/configuration/telemetry/instrumentation/conditions", - "Spans": "/configuration/telemetry/instrumentation/spans", - "Selectors": "/configuration/telemetry/instrumentation/selectors", - "Standard Attributes": "/configuration/telemetry/instrumentation/standard-attributes", - "Standard Instruments": "/configuration/telemetry/instrumentation/standard-instruments" + "Router": { + "Configuration": "/reference/router/configuration" } - }, - "Containerization": { - "Overview": "/containerization/overview", - "Deploy on Kubernetes": "/containerization/kubernetes", - "Run with Docker": "/containerization/docker", - "Health Checks": "/configuration/health-checks" - }, - "Managed Federation": { - "Overview": "https://www.apollographql.com/docs/federation/managed-federation/overview", - "Setup": "https://www.apollographql.com/docs/federation/managed-federation/setup", - "GraphOS Studio Features": "https://www.apollographql.com/docs/graphos/graphs/federated-graphs" - }, - "Customizations": { - "Overview": "/customizations/overview", - "Rhai Scripts": "/customizations/rhai", - "Rhai API Reference": "/customizations/rhai-api", - "External Coprocessing": ["/customizations/coprocessor", ["enterprise"]], - "Native Rust Plugins": "/customizations/native", - "Custom Router Binary": "/customizations/custom-binary" - }, - "Subgraph Support": { - "Subgraph-Compatible Libraries": "https://www.apollographql.com/docs/federation/v2/other-servers/", - "Subgraph Specification": "https://www.apollographql.com/docs/federation/v2/federation-spec/" } } } diff --git a/docs/source/configuration/experimental_query_planner_mode.mdx b/docs/source/configuration/experimental_query_planner_mode.mdx deleted file mode 100644 index 67e1a2556d..0000000000 --- a/docs/source/configuration/experimental_query_planner_mode.mdx +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: Experimental Query Planner Mode -subtitle: Switch between legacy and native query planning -noIndex: true ---- - -The router (GraphOS Router and Apollo Router Core) is in the early stages of -transitioning to a native query planner, replacing the existing legacy planner. - -As part of the efforts to ensure correctness and stability of the new planner, -v1.53.0 of the router enables both planners to run in parallel in order to -compare them. After the comparison, the router discards the native planner's results and -uses only the legacy planner to execute requests. - -The native planner uses a single thread in the cold path of the router. It has a -bounded queue of 10 queries. If the queue is full, the router simply does not run the -comparison to avoid excessive resource consumption. - -You can disable the native query planner by configuring your `router.yaml` to use just -`legacy` planning. You may want to disable it to avoid spikes in CPU utilization, for -example if an erroneous operation fails to complete planning in the native planner's -background thread. - -```yaml title="router.yaml" -experimental_query_planner_mode: legacy -``` - -The supported modes of `experimental_query_planner_mode` are the following: -* `new`. Enables only the native query planner. -* `both_best_effort` - default. Enables comparison between legacy and new native - query planners. The legacy query planner is used for execution. If any - unsupported features are detected, the router falls back to legacy with an - `info` log. -* `legacy`. Enables only the legacy query planner. diff --git a/docs/source/executing-operations/build-run-queries.mdx b/docs/source/executing-operations/build-run-queries.mdx deleted file mode 100644 index 6303cab506..0000000000 --- a/docs/source/executing-operations/build-run-queries.mdx +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: Build and Run Queries -subtitle: Use the Apollo Sandbox to build and run operations against your router -description: Use the Apollo Sandbox, a special mode of GraphOS Studio, to build and run GraphQL operations against your graph router. ---- - -The Apollo Router serves the following landing page from its base URL (`http://localhost:4000` by default): - -Apollo Router default landing page - -## Apollo Sandbox - -The landing page above provides a link to [Apollo Sandbox](https://studio.apollographql.com/sandbox), a powerful web IDE that enables you to build and run operations against your router. Sandbox is a special mode of [GraphOS Studio](https://www.apollographql.com/docs/studio/) that doesn't require an Apollo account. - -Apollo Sandbox diff --git a/docs/source/images/cloud-dedicated/add-a-subgraph.jpg b/docs/source/images/cloud-dedicated/add-a-subgraph.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7f7552623817811bf0c3e0f294ecd34f09564c3b GIT binary patch literal 469348 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

>|6zy#%zT!(0C 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 Xd-I`+VFCcy4eswldjCr_xij(~09^YX literal 0 HcmV?d00001 diff --git a/docs/source/images/cloud-dedicated/graphos-service.jpg b/docs/source/images/cloud-dedicated/graphos-service.jpg new file mode 100644 index 0000000000000000000000000000000000000000..473f7d6376ed2491ebab5a6a74f0e2652789b24b GIT binary patch literal 84005 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 literal 0 HcmV?d00001 diff --git a/docs/source/images/cloud-dedicated/insights-page.jpg b/docs/source/images/cloud-dedicated/insights-page.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b113aca704f42c17422d387dbbed5a683fbbc1b8 GIT binary patch literal 529227 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

TX+0(Of$m6-s4#C&Hs-7H&y#QeY<0FR{g#<8 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�AcQt4#jz4%`<8 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

-pJ04fi^agOEd#)QB z&utQ(x%Q#sDxPCX=Tv?+h6e@xrn0j*+&Q?v(9vBj^+m{uF8h23vjTz#x45FukSEWD zf#n<%C9ofn92cDgMtQO9&bHa+oydt({1B2#5?G0)XbA4{G0#PZAC`CC;~yW0YEe!K zVmk@<-WrD<`hw)|7Fn0|Mwj%ezsBE^^WK8^yio0?N}st#lo4v3u({Lal39qy`<)E~ z(nrVd^sh>P^ra{ep1}5E8pHTbt%O63c9J~YHq9Q zA_3>5IRUcfmDT+ zoB88L8UEBHE5!;abzQ$%iAQPc+XY6o$7CtBclCx@WWTx7YS!gORt@1oJw1cY?CxLm zg*#BLnI8f?UKNWfU-=3%KFp{e<1?OEX}tx4F7Xk`I6V+ybmUS5DzP=R{XoK{{xGOA z>gK5v{f)+frT)Ix=b4nu3xrYTbx+S2Z~1TBpFX=~-sBYPws$d4)Vw0xVMTnSo?-2d z`3&7|^AkY0%7Z_Wn22=wl;oQ1_s;Ov7$qQqZL}XqZz-p%wS*NQEt)2Z<-c@WjOWyD zADv1+`!`0dEL+3rt@I5_y9IQjCAbBF)u|NAzcd@^k^ z2lg(fOOeeIGcBlgjdp~t~>2} zeFKHT5Ro2H`X&udmWOWC*@xenaYc90y)Ek=21{0cr-C6FWKLSnl%p5O`uN*TW}g_B zbA40Hm<$fA!!jz`h7($!`f%Y*0!P&zY0}T~@6>;%k2&t|r&sCw+&1UtW)t+A54xQ8 z_u5h{*t>%GvM#^@2}nMIE!{GMJI3GD>D(}2(0Hl&43Jgv)i5s_9fiCXWI%Y13oM__ z*}tKhviZ^QZn0U~!+WN0o*@0t`(>$`Ol}maSyRHdAZC5lv;UEmKJ3#eiUb+F8-8+I z5O`$t_9z_VM~cs`e_h;dqI!G_V+$e$Zn|fPcjol8WYxWdv7dl#{Jx7rBLD7W#1&pp zTQu}4&vGtr$V>ySb{(tYoNgvd7ME4MR9O&euHGMgJCcbQi>)j72^Uh<)%{V<-A`}R zzJDEzaY_G9lkDtn4qO6Eg9Jr9Lfg_84Nvh)mU~q!*oxK5S7}etNl?9MwAieMyT&kT zjQSH>cBn|BkDAfpLrblZYp3or*)VCcaaz)%<|+MFtr}vQ1+RA1Lo8kNrquT>Em&2Q zWgi`+H95lJi@hr#dG+|LQO--T4I@7?=sQ7lP(>o!#B-9!1Wl&Jt7`*q*zf~5JHC87 z;Xp7`B~BzgnJ3=Yi9l=6>#x%II!Ph77=~nShFw3!sL`^pTPeD2ed2i4^0oGzgZBLi zbol;n1w+?d(G6ps1%sqvQR;OM!$V%}U1!hMX1Y0y8u&LUC;fP6{tR}Pt0LHffIg%n z`NE>=#7WeEYIed?(LP%6>$j zobfmE9F^Jletk?9h5%v|%=m1K|7~|^ob$xaW$wZ(Oc>6iv1wVKaM~{ur&&x7gkX)h z$(;@mpU`Wu`CXz0o8MUS6*AE0H%PtHYOxkj_Xq_R*Rz@)Wdzs zlgL(<054#ZqZmMYhB07AdzU9T-;@(+VcPuo9uLa7pswnzc)4mL(m;}c`Lv5;7Ps@7 zzA3FnZ%mRe7V&9QzqKQT#(VLbVe9uDS#fE@c)(2F>)jB@`)7dq&H`CW@j5nQO1k4U z^x7|W=%s1CEAZq@s?1NdFDqsT*-u_w-e;B-(Dw(vk#@#*xo#%xdy17Nj%Xsr;JXTE zp@0!3v4*l6j3FBMyQE$ZY=J5*R;0rAv(d>tQ`|U=bLV@0%srT?{B}C5t+Hv}zh{r* zvcc=(;TE|)ihsSF%)sV)%#3a5)*{o8H}nu?i5nlMqgyA zV3OFY+5@Vb{!QOs9`yG9-AwLeRps?ZA6NXm37z($)1v;aO#Hq&04%(V2q~aEh(6kp zQH*avgrcC&;sW@^3_3i`!ZRUm^~J>pTM#)#15?AW_rpPQnso`SBR1yV$DZm7aqAl0 zse#sB!baooW4U0@R|0V=AjzPry#kYzU4Y=s0}r6H7yV^c6E^txmajSaN_m1QaXvb9 zIv#%5JEkZ1H@-vsCBK6H3Y!xmyS&!y^%Ls162ITJ(flBDcF#yoczVI^ZytDzKCO~~ zK@utYm`x}w&v$IFu6-d(e6|=fB$=Z9Z@SS7Pk;)W{|251D2d9X#W_iu=pe^r-@o?q zjRZyDg@RPO|Jt5A2=+cAtCXFIF^weIlWQkWJ93fTRxkuLuJ%Y+y(bMoY)g(kWu{A z*r6CZGTLm|cO;w8aOX#T6~CtHlAONd;`$z;R=^TEN61>4T3yH6PMiNN?%R~vf{ZnR zod)mcV3RXM3nS6ND7tFX!hN}mVuFqA-0ZvU%cG-MO6R-3`?p^+emJ6X>aFJX*(VqE zY1fSrtXz@GMw-ds0fN{vR&)zr=vO>W6&I7&UiE(+ofxA>Anz%KByyM>(_ERt8+3d9 zD;3EWBq@J|ReK%{6fmD+DUOZ68{rXGElY^|tZ##TRV z&@g^sD`4HkS?rDc`c-x-flbN&^hL5;9r`SY$>H{L-58kA}PM|F|-}aMNmj{N0!9|G4Jq=jw4>d-wqFWOc62s;*|+ zX@3t!8;Q&$0cS}de7!mDVmJ)&NsM&fZA5l{zluQ9rjApzN4deToGS`@Dpi_8ooknl z99PTSz4HST!2nR}GBm&w{>8Gh0_smZh4wDFhWKFJLA3X?WLEe`P3aedl`%=WVw?1-l5B;P2t?3v$E@!ogWo{my9yS^M_hQ)89 z6KozS`nOxC!uMZ3e!brD%#T$nl@&M3^B`1R{L@tyh_rsf&wDo=LA#)}-dp!;6CH|}U+P1G@(8Idy90J9V7|52M zwT9f^{u}-rUAj+`w390Qx^HOK7pj{hy;SlVK1jAWb=DS9vvOw!Bi`49nJWeKsW;uT z_7FJikUNeY2T5ifr*cG;H3tR^aEDJJB{F70{XkI&pPfd#LY!nnyV~G=E1$FEBXR|^ zxzn~w{tQ%aUgz%d$hnDjS?S(stAJMp1Kj&oT-=Agj#YIu-YW2} z2_l*1p0vF9v8jB6@ir1Ia-D(|kN{8ElmmCQANd|F+5Ldyi-*^MhCQU_iB@(70S*;& z6v@+e&%nZ-83m?9+ZTuC&~BMdHBUs=f0JtQ?jK!bVbaJ2Tsencm11@0e;EHV1qn_3 zdFgJAf!ovCv6|Yl9W{>qgYh#9*jQVlxJsfh&&p4>RbE0p*B9-BOJra|L&7L=moQ=9ek#k%hZG`uF zWP}^v*Px#2tE_lyT(rp$BPqn$=dnRYz&YUsV%Prl?EP=K^(mcjaMU6t2BFePQXWaQ z#z3WFU$AHnm85}6pKDBAR7~Ko_k-bcK@$gW>!(1XI$lF|rO0csne`hV#+7bPbdzzf zd~LH%on(*Jh_X*XPkopG1=vOiC{w@|AjD+iWzw!0kvhLVt<%&uR27(?f%EICwA*Ym zD+ajr3TUNiFtgWh=woWx6^YhF49_XT(*IH&3*9K^X&f|j;_PZdrjpbC#77IpUKJ6V z3>Gf(f)mVVlOVqao(<~fgwF8IkQ!zmSp3NBE5tN`|&e;c}jVhSLZ<$3zf|ljiYS8$-wtP zLl|PXks|ho>dX6e3EpyUv8|46sK(|_hYuvcjdU9Y{H!pU3<20(fNgVH-=zAHcSzg) zxy@w|Xn`n23n40oThcOZf5eS3mzjRkS@isSG>&cueck_H%~`lUjSo*V<>|ZeRf-v{ z9i+Q(yzPAMBn5YY?D}KA>E$6@xBLpSZnKry%1(GM(u0t_j=)<^OYg}0wmIT5gs0gq z5I?2;0tf9R#$nIHXo`fRq46U;I*7HWZ$K2Cn^Qhx zW^ELGPm*U->#ZK=x|UPnFZ(?zT<^`ZoM-aehFYA(tBs9_0LTlKAl8aUKwT)p-(?{s zl|qzBl*1?PzHFM@;OYKq9Vv9lb?=4=l(IAb4t z%5ll;*?hS4p!A$@;EU zi}Ft83k7bXJ>X5u(NqVWfJQ)EM9w&S|F&l(gqtXqyFBts)#LW=i}Dv8+BWtWbyDo| zF~JHQa40p^d$k@*<&x40LNcxOIrWOT?5=p?{r0nF-T*vpgMzYa;$MB)n)v)BgWVnP zxzQWnUwQ1>1hTq0dpnmkc{V@zkY<(UsnbpdFRQH9Dw!tDqN+t6V_=TGOaclaE?SAu zSu%ytCWawpLlLTQi8A4x?NM=|Ljyxdph!?@qz5>na_3r zu{+*j`2m#iI?#zB#N;Rlg<}JuOz()Fl!MG?_@fQ~Aj#oiTvS@SBau^OZO17xyOVZi ze4_}~<2LnSs_T${(9EJsEy<$Qh9+~YDKN{CB4#SZM898gmDDN!regLY0;g%@8S&jt6_GVS<~c*FG!Z{21yWNegpmSisEvyoKMneF18t{zi+7FH zNpx_=!ai-Caf-;KZs6I1TxDlj1jHAZUO!7P9EhY z@OZ;w>mlE1KY=j+vXx}_ZNP4pCOS4UMe9WY&j_l}ex3%H0wKuZu+uD8ML%fomrMfE zY3qrnA)yZV_C?|(A_Az(s^~F&x4^oZVv~}4&uvhvNm1vy&cb~14p)+`uJB}#T6MKT zo<#=ooGQA{INkTq!14%J2;J(~&@Y&6l-Q0@u5{9^73V^&QI(VD_Kg@pB+b-L4cwAn zBQ;~^j;jy3+&3p5>g~7^vg`ED`wt|oDe5PYKNfgL<(~-ra7izJHVBFqiIP54V_IMR zq)sah6n9y*xfdzKlSqxH@yh&oQ z7)a2eE@tTt{fCZLp~K@tcl)P#)a2c1Wo~!EJ??}LSKoN@=~ej@=Imw`WsFsP8gelk zz&)aZL>szt`&w_q)Q1!Fn*eyAU7GQVR$oezZRQXLIr`Be`m{>+&I03XX`3|s3>Pfn+nITam^zL;%A zR(C4%F1(R(W3#vlOtovQpKmw( z?D3o$Wj&UY>%HUfRD6Y7gjs#?=b8x!SJk2OGYI*C?LOkC>$D8*y`y;NIKX&7P&_8l z@&{ROo%wZSU}dvML%!^O)I?a_y(a#?&KClM%cmdxfU- z@<(fn)ltaF>Nf`l9lHmqR|QdRjx{%70iZsI)RVmpdguq*FLB{Jpe~U^vgkDA0YH6E zLE~IUT=&fWcX&iCj_HG(Wc#(dc=xpy=UfU);JP?QZe;l_V5sS<#(AGTCPMb5W9s}o z1)U*hFYWrc7Io*>k9Q(nk2?+uRaW(Kr`qB>S6_WW^<^u8)k~7yP-?opS4_eqxGu=9 zRyfbMUNXeq)~SQbIseMp$R3dvboiZ7gy>u;3uWz=_|PS+?pPi^7_%;P<{etpEJC<- z+#aR~+KyKlB)ac#v``KlC7UKKkVgU9mUgo$FtPHh@wLw_ z6FM!g()Ctn#6t}y{eCPt<$fn@_)!4oWR2s=1h&eGpt)s6NHQZZ3Mxy4?jjS&+AYJ2 zE!$}0^_{2i4&Y7wUfCjfZla7}5uuLL?|A@nVhTHsFR#R0s`rBwUwl3+tnO)z(YWKr zdLDWquj$5`z1dX#o{l$5tlF+qnXKIus)X(yUx=>5Vui{sGilyxjE)*WJ=I3 z@H8LB@#Yx-NpH_HI}e1aXv?)TtP!>0s?DtfX(AWfWVuJh2VYDu)OJj44bnOu!kQ-w zlS694p9k%3!TuR^BKPR=GOtHEuGc9p`rFH5rdngE<6me&%i=$(Y<~DR)sp{*gvbA_ z{`-F{&Ae?`Vk9~O68Ynt?E4aVktaY;%amwAIbA=6qo9V1c00ph6{pv-Iw%w9L(0X& zYjR82%0;gmcEpOsAN>~n68kzfDDC`-;3G~Z5Y2fUIYjiUYg0ODUmm=>rr)u$jVum@ zMEi)vNFJ24ZLfjst%%sAiU|Em3sZPs`h|<^C8lb_B3w7SNgB5M!RuhX*I2t|oVnPp ziwLt-V@;xuJ6?*w$h8Qj1!YecY4X?y7&2PGEHH0W5ZK@5jrVf+9^#@PpTX7LR)(8* zn!cj{Xr_lt2$ibJNmaZfubd3Sx&kXiRGs?ag}&9Y(fC>v5L?gNti)ZJ*B~!LsfF># zT+R8i7x}&UGY3FQ@U{Rug&ZSB2}g~fH#K*$;DWK9bD%%6!7;Pk@7jg^si!1ErPE&* z{i$oWTtt6ivDlILH*%?NOe! z1OGEbj4$lcR(xlBz&{WfCw)iq9qv$qmNv6@<@v}n;*~B=qAf|T-TG#k>@|%xiigA&FpN%3uCq|UoU+>{I&^?{nM>DC5PS#Zp)RPN@=H`3`lC~); z48Usv3d>)iO@AP+k?g`7jpp<~)oxp5$blk=q1oGU&Q5OG$1H7c3lZR0|L)bgeJ8U7 z6vAj{N$ui|r?2Q(bj^_ce8r{%U{`Q{F)5in`{t&K9x*Ecws%s2&96M05%4thEZXDq(=(yBOvtrQ%Rpqh!WXX z&=7tQKSS6&p=2*E~$rjPy0aIi?&Q|{a*_R ziyf%}^UpIjw5(kD+SG{BbJbwZY5q<6#^kX&YpZ9@`e}b?A1x#=8=BTW`Sm042EIJF zTre3lSYxz_Th{XQZs^JnBT@{onpWj$ML8g?FOg<6A%S4Q<<%j+u zNQJutUIOZ)G8fhwI`;;p#KmT7soJl3iv5?RCgl;jHITeU;rDnq@q_jQrWonPdJa+U zgGepUXQ=WvCtD3~+BQzbd>?k>tK!eBxU|)|F^6QV;a#J;ig76TvIAJGktoa_myeg0 zEIrFSr)xS1JZFb549PP=gQ@a0>-qk{$s4h*=21b;&Nual(xe7956Vb)$U?t-yXY)P z0(7{@*QbaaWxi|2&IT?mnWTDbBSO=Os65G1Kz*1DY$6a1An!?(B zIY`B@0z%=j>u;kf{Q`TIJl;Fhj>G1%b@O6k}Cn?IW@%bNY#)Lor4;{FnN&K zi%{4YNr&^_p+xY}U_ShwL<;ZMN;kH4;il0=F!BO(H36V`FtQ|6@?zO}8c+wx;l@d% z`MJ53g_z0!T;Vliy*6mjp2T{^fs~5+Sn)^3`^!J(K4ahtWL%Ad#;3h= zPtB|>B<5{&)aFFx<&h)pMCOCVc^h{b5ngX> z`}Y+yUA-_OS=7S^AcU0OVGGI%@$&^tC@Y_`kjTh}C6wbm#Lbb`30y7x9>3{_^D_p( za5B(2^*Y|XumU}!+|rUX{`&d35|DJJ8Ir;IAb0uvyJZTgckdM1!s0gvdRmc6g;Q!n z#hW^+%bS%2F~z-YvZLu_gXt1k<9(Jc>T&scm_zPi=HzINLrh*PY2mZ*03_N~DuK#T zf=Jjlh}Gtc`?Xz$)>rjS3Z?&-FwjC3Q6?V}^N~EvE?Y9O6EP993y7~ysr8Wfm-OtW z6(68AFNnFKr6q!x`;L^NhEn1P4A;Q{M7?a~6;($ncjXZdlSQUNwWBd==;p4g}zU zV2wkr(TfD?8MgtLxxNvRE~L>xN-{%EW(xAgjg6T?Oz#YgX>D|~1iZ{OC_Yz!tH;O9 zG9KPEV`N={?QOT=P8A-RbC!(`cv+2Sy&M_Ht(TOAm&V zajqx5vbF+hKs(fb(IXz~G!R3FV3v#mB3pPNTx1qPS_H4bp97U*T3X?vV^hT4i!(-` z5g*Cl#-0R61Yr2^4*!_q8Gmy6+v-M_t)_I>X2WFX(uk7eUR%WHN-! zS71qZxc~_QwD_?|7oc(3S<4D(l=k4+x2wu{6o0~d^G-QLyvA$lr!7;inGGJ))3RP{ zCYUAY$F;Vk)T^-2*XHssCV#5B_{Lyncr=UFzFNKBQ2xbfLsi$($s{k|`$@f+9wEM& z-A0?8L4b#7{ixfpec8MXVK9hx2fTZ4mo9k`w?TRuMQ<4JTaOBj3(?Ls2suRgoINk+8ls*gX6fUmqX+TEQ}#A=`qb1p zbm2$PU_75;sITt3c3R|I=wJ{V8|$1H$SYZd0XP1l36bU;cyVNrkr-+)UM22agzbaC ztUmy;RlpKAt|#kz-8O#q-A)a=>ct>qpub~w=&)&=?ZFAWP956TDA^qt{zr@CAR_{g zykwq24zPWYu;qm1W%C#6XIN3S)_F`18bt*DzgX#SjnQ(^%RAU$IN6cw` zzD=7gLAAssVd2~Ld8a72>~5H>sg}QeD{x1m4G?=M7N_Z^f$+0{d}&q<=>OVe5^UzQ zt4G&;7^%m-m~-V@WMEIhhbt8BV#UD99n6``PlB*hrmJy!t2eKGtZW_)ZS{@*)$0)c zWd=V=K3 z;Vk>k|7OK2WY*KcwihuI8=LGogf-?G1qf!KNpiw$7v zdAzw1)d11{K-bUb#_`cW^Nf(IkSg*b?I9T94Vdkx$ zu#^l7!kU(roU;@H$4Y5wZsSJcS4VwV2GOfw36yAiM;nc}6{y!l%B18obN-wvuwBD9 zCWjB1MJyNa8Uq!U5P}`zI%DE2hxDE-po2z2C%iF`-JLC`nJp_i)lA~hCH1v|ekinG z;y|XzX70Rq?-&v$U?+)uInzpkV-aBEtC!Eu*U?Mkq=zWZi)K}>Po5ON*sN_HrC6G> zYyxaBJQ=eRucNZ(g)Ip+RcMBhUiN1+$0Cz93%NlcBD;Sz-7+MdAdBdQWCz|3_@yL) z$?kary-eD7orkmFJO)J7PfL>ME|^C<080aJ(O6xIdPQ_QHEPQ~1LSSsRs=wZNmBXD3QBeW@8Z4Ufas^qN0PRt+n5RZ`p9D-t4e z8Ex!e7eARbD8@V+{TLlkpWFH{Y9#=b#L|m|rhaYMCY9C+Okv zO^xFa69>YMDqEk#pXR9PJ)eLc&UfIiE?#qIfGaFUQFKCZ0@o&d)2lFu|6pvTVr;fx zs)uFj78np}!VcumMICLQxFk9mH1f4@dg=u=SHyOw!MmLmb~};zNBx!v=WAFNE2}sC zUGnX|J_qzg6str?*nJzA`Aw<>EN&x-GHEL^qR~$S5_{6-aX5tFv0ns6O8=FKfKWut zme2r4lCtC-=>XnH7(#$5IO?V1Cx~mX-TpqT54eYXI0qo#w|`Liwsd}z#V9NFSuE&G zuk#N*0Z-X5{89qeJMpFOP?jN_D-Qd#IqXx|`uq(>&#NI%vawT5y+d#?VVHGo+|LwW z@r>AIM4PRmH4{2!|A_)}MqHywEzugY@0jrr0d$Eret#0%m1&K^mOC7dD(oBWR1%rK zD|y-Jg-z?VT%S4I_KvZ(mZ;Oih&xtpRq?`PtMgEeQ-{ZF(bvn&m3!Vp({*>nN5vhq z*~dhAs98Np;|xG*ui=+x>$8Xz%ASz3mGLEzuoh0DuA0^+42Lx*b`dNJIRnzWq|^q{y$`xyGQf0W64YLhT7-`kB{m zVGE}_rkNSqOqW0hC*V^S$1p3wjs9r7RM@A1OLsj{bMeT)@^~wB`Buqvz}T2N1{QsS zlCtd*aPTH%8h8E~`u4&1iB6!B{k*%w+NGm7kIhKR3h5&?gMiQ0^Nz8q);L|-ogM6NL0JNk2odkC4MY1 zBMg%iq4I?glKRULB}B~;(;)BMKrxdgeZRC8fVP$AA5dHz58Lv-`>CM=(u&-+pvt;I zOQrhDc^MXpEj;~kS6bSsO3!~i@}`V@($PLRp(y{M?V7lXHcMiw z+gd>G9imoWCQey(7wdw-WD#6kjJF6b1IJJE(YT%V1q&f96HYyBbwA>QsHd1w3FTXOhg6S_x&y|^|9%#WfTB=Kr*I%v@9>IG6q&^yqKxb1!vhW6Tt1J{(I_+5dj!S4j zAQ!~sWOvu6#wtxNDuNbWDy-!T;f;gO78&VP;af%PhH%p7!wS}0_gkva+Y(j!E|i>{ zD2iXZx8!o8&Ux*OY>*E-Fo;5Yuuf73^u|xmyCOWjgUR-j8OD1KV~NDa(pA}gx*mjYQl5JZE-CX89k%9`hkOe zLccFH+FsLTMmep1n^fjMpekp92n&o0dc}>zP@6a}pok4kiuy;VG&!khNKfcP>fQ1M z!)7zH<)Z8n^s};U6q~#*CzX@ySL%`?f?b|VD+jdxo9h?{Bt@0t)t<~cWqN+U1?=UUE6Xp1=P=8)|57TfBhKh zD!Tqe_VSVt4%ToG{m3cefCM7FUu~EjVTEwzQ@Gi33-K<3dMq)R(_wX*v0fB3(C@WX zoL2t+{f7^Al_kH9QMJP9yk4HspU0}}EK1j8Jc3;-_1vSPC}xLqh%zo_hUKm6*S@OG z#z95C^Eid>cv1@S64bTk$Ww%R;kL*4p+Fg!-^HLQTRQ?#x{ON9UNGVH%#rbpLW*ji zjuRcxbT}2R_`&CWZHoe)fr(CxstRnYt73ook!;`e>s(6jc+7!{w>Y5#GVrpx-bC$c zM~B%f2nDY?i&0p3D){eB+}li(M88y5*YQ z5#}?UUS~;iwAo^Wa{G5sC<4S!AxGNFN8U1qAY>+esJ&G94)i#>Q@<7X*qqLFap)Nj zwd;#-FW%F_D5KB47%i7fLR3bxlRG}#jUcx=#NF$xy7OaB>b^Qy!GZBd9|Aw3%_)C; z#UvPAd%Wcc2swrGBq?a#6{c^^Z)UI@{{zI|M(lSf3z$yK;4NFL26G}JUG&zttT$hl z8=Jh1E=SuGRWKj&osFpNZKaNjvGytz8aEgd6S@&i*@i6(C11+`e?cU)Z;vFyG=-Rv zNl0F!7dh!J*y@AB{&J@p0)~*cGqmk-KUrc{$!K~+qPJIa=Z?kSu=ge zN^HN`!#i3Y-(N!5{e2-a5c7VH?4a%>b4TB9vT`DviU=*8B7VOakh|X25<7B1oD0>D zX!}LF;`B~4$skNgbg6XF9q&CMG4ngkWy=OFwl3!dX@P|$4o?^S>Yi@Rq;qaY;*q~( zV6|LFja-Y2xOcgo#p(go82@}b*&~;#FFeWlj8!#_T&}DwZ1tnCrv9h^@&(t$FRmdj z)3Q)6RQruW1aT8hP2wUd?KYxuHOpEqkuNiHp*`~=V3ECJxcJWE@q%@LLTK@2y)3$)whiiAXTd z42j^%?!udKdbme;I>~+otnr_l)5{-wBPZ7LUyj1H##oyta*qXHsq!jP8;eMAbo=!A ziTh-rFRE@PD^&6T!cSe%!VD1f#VJIN``g)7Sx{Es49Pgrl)^PsUOhv{GEu;7@Up|$ zx(ifSc<3`<@F8xiq9X6{e#LVXRG7-}-7Mqsz$bT#C0FU!SKNAT+~_yeD|BgFD}Q)# zbb1nto|s2qXp{8=D5^sjMqYFZOn_p917kfqlO~T(jKVn8R!)neY}J&i`|y z-M_Jq{@Z}N|KGp*ACa{F+9q}Pc|Wb;vYidlWntbL9o1?)tmFEUBUUqXaC^Dx*cs-J zB|q$IcvJJ6{7G^gb-GRFZGz!uL(Tb1f1%#K%a1OZZ)p*gos3l3vxS1lhA`b!3i{wj+eD0}eeqWblpOe3C~7B5OFo?XhAIWn6B{n_usO@)3kOuutG zIrr1EyBXhCKa+VX1$`UczrK-nT4_(!Tgthzg($R1|3Q*hHnPdZHT2Qm24}+a%qktJ z-xNO{{qE#}g1Cghspqxz&~g^T-PHcQ{RF=cjW^CUn;yjacVgt zc*5vV><2z;#!)GtOY`}j!Ton@dk!o8RNL}`7VUKVpBeP`d)1VGQTN&V=BFQ$empIm zv}-oGYyWqo$^{MA?ETLdG=hpM?5x)UM&t{FBQEb}o_O*$>R4>U*@wu3pBw|!4~RdR zMjn1RsXHI~|I$3`ZC`TwX@C>*eNF$&VZQX;axj65*ge1%PMRsG<1TYHdr_L8ewXdh zSGg^JU=h1REvM_UF#E@L6r49jM;ujojOQgeJSh5N^3dmibs_$~_3+v~{UiNB4X$i# zHnkH95MTs=fJP_upzc75i|ul=*$QWV9b4B@kv@O%&x3VvjB(vzNOshdj=7>uD60)` ziEFK^xbF8!vc`=Klld^8a?(8`<>a%zYx$q2Tj*^q^y19Z|Fp=zPyYYF>+SS{x-8ni zeUp0cede3g_zdZ%Vz$}WGOzz;i2pVCx&IqK~f(Pbc>sR^ez)pUsczM9iGComh6T`~r3BWL2R~9x2dU zBJv}yVO8X@pF!e3h~0goh|f&VZ&EZBlBnoha?wo*>=O)Vh(Uhcpc7a7pk|Z)#a})L z5!1e=iH-#-NfNOrAs-@S3{Lo*Vv;zLOMidzf0^BY;3?bA6nJKhZM{FfZK!w`zGAT7 zrzgtf_G0W_Y5o1s11+!$4#s-hdplhCebEk5sjo5Ilj^m7@97_sADnMA@%ej*_kUJQ z-nKhn>Po?ZqqRTfyWKv#4gAf2`uF`pOqS+iX~Cfc{D^Y(iGS@*{70{Bgk5!OIP}jU zzxL|B`JVVn`D1TX{pdwyhv&-h=una2)?z67zRq(;wNpMDMvCtpG~fJbO#P+z@I}Kx zo!@MI=IrB6dU*Z%o!wvD|1{z?KjMg%H*_8HV}Fw}oR_UfK$xrF{(k%KJ^9-p{yq)= zcU{2)5CSaih=9;bHQENv0ICNL>Z|sU_V#fo-gd9(5X}{5;BQ92xXKcr!9*zbM8dvGZjC}r$&`$zx zJe5*VC9rPEOQELPTs@^?q!d^Oq@;h6l9HFIk6U_TBl-tYbTI#$lnDv3VSHGE$4FG` zC7}x7WfXYITapT)#~?SU^cRVGKCSHE|NFFwmpNbgG%$$v^(lgrMV$SJ+R}s?q9~E8 z81YT2R6D!w`sUgt1dxgn4a3~H$j|-Xq&V^4q(0q(fUaf`XegIBj}cRee5>_uQj)vz zwy%2FgLfc6usZR}$wcRL#9u<_DNEm^3bskqm=bv?AuOQ@=n$!X73#Hb9h~3#tU%OL zg37AF&}cl)-{1Z}#olidY7o2L+}Vo{6o&7`9i&C_PCZJV*h>t(vCC%H4@oBv{a>0z z@?YkYj&#=^%B>^A z!gf_uH)bTdI}MUfKWb+jjcL@l@$sT-ZkX$%Pt(gBc*rTo`IT~}ePNpe&q2^f7V+ss z;2Z?-TI+0&X0?71lD)W^fe)I1Q`8ON++Zg^n9sj4p_}du%Hio~A0g9Y|AB4XT z!ruqs?}PAn^8D}b6aTfmqDIr6S;8S`SkykIr29E>L3hLStl+EU9zUb(f1Y8!jcu*` zP3q9_V~ET|+PdCWl~8EMK_P|;3jS56^F#-Aodx|CJxh;l!R#E|Ak)c#q*-!^L#Cy~h%?#9KrGh*Jdv(57#;E0|RF*YH+gaZ(R z9@QuL{yBZU@MhhHmL)1(TM5vk&hBibHr-w+KGN>2qj@zcW?Ffu@r`;ycpSPAJzb%f z+d?-a=zj=00BJ7aFF#$-J__8Ym4Y?hk{`x-)ClR`;sf++*db~EvHHutwHr1%KI8hW z;~Pe{D=NMb^~dV;nv2bS4?UPjK3yGFLyi%kJ%*~Kj%=Gnv7phy5kd{gpzRUu?a(aC zpW)egnh7=R?I7X|!}@alynq>%PWj0He!jUetP_@(5SO~hMl!IPT5g|)xied=e)Orb zqGSUG*@flCeBq5|OyNg<5ktm&4LLa?=mb{CT;wg-zL*hByAsC;g}duln^tw#Eam0z@~r(w9j_Utri%Sf!zVM`Vm~z|j-&3gZ*JYIt*d_1m3u2V_=g$; z^*!a+PajA+sq^6U%ONo=xV62b z{ng`#hLD1NXn8UBX5i(FBQp-co`=6{cq6g~^MNlA5`I~P0owW@nqk^3?@Yp5f7pJU zN#J<9!_%OE1?CA~c2`98g14%dyK_j~{$}R!0TWZDe*SsoiCeqPba740n3el8e<2vY zTP>D>lyE{I*n7)}_+;Qj$507SPx>_Ea#>#jEhFn8_dL~iNDAOJ%?=ysfAO$dY z4tC2TUt0$F!<(j#2-O9Gr}NV!h9hLrX$ID6NcFWu>J@_`vYVaObO&gukd%Vcu8nBy zv*EPm=926V&%x*$<1Pc|R-G817+Z!jmOAT=U2FwN2SV6o3F{&5z@g3o>{}v>(jJKH z*If{J@5j()jbnTNp^9`qK{?Rita(0?H8+$e@C|v{{_y7K0tY!a$HTb~M|IYQiK^i= zzy+B>(q5^zmBBGK1v30Tc50`^={Z{J=)A`81ECd8*q0xTLvr)7u)vl<3~B$lSvhZL zh!uQJc^t1)iO#c?4RrUR^C)$*45~kTPpXCBL}3(Rkmc>wyh_s7PMWVN3T+1XMvA8YOxl7=0;X8LJjY<@n! zwT{Y-KzU7&$632K0{41rxR61SO46Ip9)!{OB@ykQi#8xlGqC0 zq|hA>f<7<`%SEO^LQ=5gRqKOu$TW$fw&oZ_@E?NbSXh2)d3u_&%2Q_Qw^2v2&Y4+O zz75T7^mXSz*F^^U?T{B5n0Cvk;wg`Z4;kK|nNz;TZXi?}dnsP2ck5&S6spD=3Da`)&M{X|PzIwP5yh^eWHNndYHc=V(->6wmI?$L+QC2x2d1ypigVa%G1 zouEft+G!%PfMQ1m#2m8i+ym+lc(W9G;P+H*;mCCD{mHKHRwD2hT4P2jzqNMI##X5Q zh=Y!@;(X$-{s`N-Ge^t+tZ~bTy;qN|B&UQUG-#3VseA!lT;91$@|M;lpC&XCsfZs? zQHN%RS?ZOv_km%u*lEZA_nXd~JdLSeF5H_RNF}7|v73hAJQBQ^he@r_Aoi-xp+EMa-m#OyhA3N@6A5&%Br(E~%4T4S7niZaf zC~eNS!aWV>S*HeFO^|tB7sKk2pcN%vyGZywVHBY*F(yp10k_puq9Pufz$I?O?}ZpK ziQ71+w3Qg1{IJ5VP-r*;SRWi09EPn7i}g!cb3t>&+Il(OZ4-JIuiSfRIB4Re>~tg7 zX*6>2gp;9*8S&%9SF0|XGA$g%%A(CSp?2wt%gjjI-$SyQX;Ec(INiNVTbVi4O;TtQ z6X)LXy>Hh>9L(-%QR?ABz&6n0XP|AVHLr?TJ^!FOyxGX;&l^UsuU4EA|7tDxGxmP^ zWKdk7g%dL&@+LyG4-$u^DH5+hEclRK%oMB-rfS?C2PF3tAKk2!Bm>P3{RgIC0I> zS~jdItR)KUvPN=vCT26dP@5IOhG z_ytQ{N!>N;@1nU0Qq65;u?L0qbCnPeT>3j8(m^2 z7uTuTisEuCBXo+sU zca8okqJ~a0-*_jk1`}qdtvDmM@Cv}@`8?ky()T#Ko*=n#J(AwdnAJU@&3?L%8Y6FN z4n1V`>*bs{AD5GV`ODsUr$OUE_{*iop7h*DC!QaD^IADrXNQkABsZ$C{d%anXdM?K zfFfT~8nMevVu1Hd6TrZzSp*9u@C94AOW6k|p^2XQ8BL^JU=F94ic6ZFZOHfK!%|8W zcHFa!y)CXHJ9B-g6j}Sx@`?3CJxT9}3pb8u)-S!+d(k11k1-khJ!bAiIpk$kO)*B!c%bWOe!i+-UQPM@AQqcA`MG_ID!nZyVfOMi~GoC$<vxKN%GmU!X{7X*aE;ssjgLi`Wf6N>x7x;etECgBt4cPx>l%rI zeEEtK@=i^Qt{z-6l=fm(iaSJ8!r_*`<|!CTn6%xr2-uXuTnq0Mhomrdjz4e~=&z^* z8@mYyfoTXfwE^Gzfqj}1F3|u4nV5Pu*gtR%2>)P_Y6^|@voz1Ktq&{hdv>Y3P3H7i z%K3>ZgNjvu4|@G1I>Cr)Q!kPIPIwA`Ra}L*vKtb5-VIG$)(^5Grg!e*%gm#I-$3sk z_0jdaRO$o<(ImQDhf8pPg;>PSEq}hC>h_iNGU-Bg6I^k(E9sc$^f+})#5$P`9$_v! zLba!s*CV%KdnHm~{PzSV?S+6mo4pTjnvm%K(pKFnz(b*CG|AyZsg(X1x+9S5BA8YBU znRDvQd{t-8?|kz+{SO7D^={8|KlgUs*LCn@2XwCr9p>pdHL>{Z1c7}AFi%xTHHkyQ z6A~t4o7jTieiJY~%JDP6L{RAL${0+6=wnzOYBNw~R7z1G;;aSp={%W*ZKiA#kFX27 zdXY8rPO&|i7lFsjv9DLOvd6%5i$7)*Tx7$?Phd*PkK>)qgwVQ4*Ru*Ry8qN)=+UiW{j!vpbj5Ug zD$m~2{ZxN>xwFX3&EesVmpZJ{6Q_5DuaVmN z(Tii5`|IlU2X$_F*xYFr+Tyi?X^`+*-toZ;Y-~|zaDV1^>Gcx^>;DRWqoM)t2L=d7 zb{>;%sTHYAXPfXNV`I(Lut1k2&lR$y5!F|kv*9mmSbGJqc=Ppv1u%7g_FR9guYxHf z|4RBrMz(#{??fk>_Tt$MDsOev+q3%8s{`~dgrY|{h#JH*Ng>FsFiDJ`C1uRfKgkHb z$qkZGDI_l>)b}#EfisM4nN1^W`03GJVdlFQFG9Fi;T`c$2IMX4U-Zz?iC{`~ju}^B zSZ^59Gahzz@#|y#;4jloSY1n={~Ns;hmnzVVyLzGLbuVNj-;=L_cXuxJvH z!1Kq!1ye9dbg+TMVrnTy_?^}XdNc?BDMG0KzdyurcpP)_CpxI)mcdtTBOT-{7?eEo z%THhbujMqsWsM$F2)uWsTTV{kx0)E+uh-Uf>^$~Tb1e5(N3r?#{F}dch~Sn)3M$pU zyX^O?dpoxU_^>TEq+s)31aCY3TjHT#leT}3I@x)$&dqk`fAAaYhsK$P{{Kw_+5a>v z@{bzZ|G2I8A7AW0XR%-N1lHL#G$!4eEV7_9nT8m|m|{BMGGb4GVnGIkL| zn@wkp??H&jbsQH@p9a(zb7Nz5Dl%@?Az`rN>ETkf?yR}Hfm<@%e=he@2y^MB8qK{; zWe*KkOic7*_(6o(wVH9s{4rt0P0y(69<-aAe{YJMLyXjtH0EZ3$nHlL?{@at8K zS01}ax*je)Bhio~{R^jbC2j6qL=bo3CPyAERoamFpe}8q1-1uk;sp}`Ny30*oGCV5 zknSMRD=0B|^c2Olz<4!yDdIa0S0 z*a)K_89u^637&{lWyq2CX12yt3}P=sc>?XG>@}&FWINpHKFw}#!Bu*G&C?8=zmg1D zxId%{H*@k2Z;p=1bsNd_}t^vSW9QWoT_syFTkz3J*t@W$flP2h4)i^O8wX$ zQX}xiSdW^tVzfR}9UhGaidS7*A*H6jvr91K$O8P9EJstl2 zD#9KiaUjC4=XT6G^Ffui+N3Q~x7}kPilp_Fh;!(z{;_5)w$8YmhxHY>$AQL->{O?Z zHw`D<#nMX9mDr8gw`ZQOCC<5B*k>Q_dg+gZG!47$*BaAm`ljdl@?b(8Nfkr!FY5UX z9UYikY?GvFgUvv#dqh?QYjw~))!kqzDdtXAPZ6$);IR$%yhgLxqxwYzA(lcXt>_+n z$lg)nNxyWiRHbqvv8Uc6KWiY*w|^;d-Hn6(8HJB>rZSRh%cqT15Q%x8Jf|~i%1b`$N0gK6>3;oN%zp2s&`-x2zNUS7-e7;o!0o5H z2>Y}fuYY^6_gCL7oRq+{+OH{TjlU1hEGdAN@g{Ea92i~N@PeN_+a?N!LWKt#CDaCQ zo+ymYjA5t=2(1xt`IALn7yK~_vm~S9$yDO8CI{}&xF9R(kq-}jJVc2iH|ehIQ5L%D zbK5~bTYY)R{xSWCU6zmi{l?3WX|+b>KKRi2UF zZbaJ%wUN%G#b zPF=TXMP(!H&fu5lB0}qdjMRFD0nv91w7R-tkg8&3Z22dmJ&ze>ZZ@{C{XCS?|MnfG zy1M~Yh@P&CWK>}br%fB9YYG$_-)em}4lm5X?`i5+efe?AZk1DZfp`1nG&2~&$S#*B zPyXLT4E+y3SO2|z{GKa;<~>^;sOtG#Whe4q zTEH96&UVdz6DCUv5HRu^(8U9CAT49*377fFH%TT6TQtjmO3!GoD#L72agQOH<)6$f z_ihbuc>VFy6#tTw_X`H&#q*w7+QQs#%SFdocODO?h$K7byTPBwM-H#R z9E%=XUcnmIzq}xMt7p(it-|n829QqCzo;9__bg|bai?)!>mWMU!qfuY#@yU+RcKH# zG&!eNo}aD7Z!ax+D^x$sFEfq)%E%0S+N7RUGF6-EpWF{%>AEOvUP;n^#Z>y3 zR)d#tp6a@SnDGW}w9#TX-~CVKXa*2lbl~nr`VJzFQ4r`%0%m7goQHqU4iR ziSQ=IF(u64t+o*b{z80vMgaL!uz)tD6i)lZ82I8LDV?R_77;8Vj(~jkjT9Fe=AZOn zK6O4-)D5-pEu}J+uy(LD4C26ZW_t_&NNq_WQh3x3W(zNh9SmH=BdqBL` zoBQz3-_#F)#=x#t!v*NqLTS5{wVgo6RQ_Ify=MZjkM#|!+j}@Cn;1z|X9B!x7IMVB zl%^mi0c`Z&Vacn6=0Pd!v-k*rB>XB^=;(?$f=fpjQWW5E{5NBs@RnlUdBa*h0U)Nh zyK7UWirj{zwh-9PydP`)=`VUIyoUH{A1DFP-pIL1nS>E#Y-Z zd_!ajC_~3a(P?b>n0BmY5~m$h)5JDDT-XMp!P(zb9M-q0AE(+1jNUU2)yDH4E?9kR z&?~bnsxpe9m0-imj(xJ$3hZxdP7SpEU>}^7vPkeGrI3r>aez|FC}=hXbwrH-0FP}RUddY3Ifaa#!(vp3`fpjm z<5k%gW;ur*AL$P0+shpX%CxSjBHAQbO#X;b3+6<@t9;v-Y%{x_Ir2U%e4BJ9v6S~A zGat(qo8pu2RxfOa{AXHguGgp^h-&eyt*-8$D<4DSud122#vBjWId6up9#VZXcw+IC zvz@r|8htK8ccDVEj9g=A0G&wZ>UF)sD2ts0KsUU^4=z_G#$iV}vD8gVv^&?yn$-5d zA8RgCexD)h4v^fDEwt^)8;Q7Iu+?)%vAO(-_=ROP8`r9Y<~O`MP8rQF9gUKbHBzGs zBCO2^80mP1>y<{eu6`PHz-A6;2{oOfTorXCdr(_&$mn!q=1!9HC>*l>o#ceP^CZOp zhGnSrdiVZVLk}>7Z-4##Vj|^r1nSw*cD#9C)@`ZFp;9$N9g$xU*i4-sD}x4FpCz#T z-znzET6giDV|){#J5<0kh+=M%DotameG|os#lwE;rUUy0SA*M z@7|KF-z#=6n@oS!m{hBleZSC8SbK9$k3KV0j~>EZz2D)!d+W77?uN0u>)D5djhXlm z);Kwo3?xkf`N=IN|11*H-ZZDoFIjozG4LumsZO27r?mb|G8L#Z2|Nd68$!JrDjmIF z>;>7kj@j_vug2u%TfDvKpCP*v8{B!yLg#ef(zlZHL%5w-SzRMZ@Xw|3iT?75kG1C+ zZVMsrYp$cO*HRSB@+(Es@+ums%t4H~CwzpIWiLAR6eZb?r%0y?1>)Zm!V z6uMJRQUo16J%TV19Ez4a0U>{|r(NhBAm})!kJ<R1)~!3;^c62RL0AROEaQP20_$E26UXqk2S-Q zUGpo#KP5GYP2|_eHHVRYnB?%biI@hHQuO4*Rqfc|2r0CWq z^_-H%^718GNThLUKHKBMMa*<98=p_uZ&eY_DpmPoBKwZL-Vh-dnJuxGZYMLdBN`)` zkB7H$S`(W}-dY7E|KqRgOafE-R-)#f|d5-NXvgCEi zs+}@6R%xuq*4EZ|OhkvA;5O8-jAl;k56%97i*$DEF);Qx>fhn2!Y|8AWTD&U8^o-6 zGD!;5%v~_IDeJ+3SO~B|SCKo(t>kqe<=ba&&-ZRdC`$4|k`;+p-?e+m+!|AxzY!C; z4s;8-o8ss*n}fH6a4cr47xqlelr~l(u4l03;|mJMjgH7g6IsD|hrA9s&_g=$jr~i^ zNK_hSbc*?1i}`$$B>Bf0MIdpb#t)I>eDO_&00UD3CI#t7`HcoAnsG7WoeRSAP^v(t zRY_fuZ*r4)g%&e%NPvl3HVLlmuGUk2Wg02Wi##5!m5n(tqI_h?qs3ylx6llCM*HQ% zgPs;2O7yIwPuLFX1mcCZ@MI|fG2hB)(5CRp-G7mQ_{JL*PuU&ZsE;d6p6d*4zcVTl zb;>y62QuCg(JhFL(EYGW-iHrqKKtzNkytf2Waw_1n15_bnFgtG@V(%zF#3?Ke)*82 z(9VW~tEZlkxBu~{Zlsz&sHc}v-7AaOun^?c zDYbq7nyCNtz7_Vpa8`teh6Hg1h2$M z?qJj?OH=%k5(_e>czkT7U7eUQPZ2sU0jWjZodbW^X!uokX4&rEj0klgemd{$wA;Tfx7z^ zh*`y(+wgRgH=iHz(qGs=K4!@>*L`}jFpGhIK;GA9J(qD)A=e9m%6M$5`Sn`>Cz`25 zL18L=XFK^_LagKgL!PvQ?;8`0j@&uGl_p4kCRAPEP@3_)`^jP_4{QxP6-&B>iesD02=w{-EtyN|2x((Ql}CZ$t!fHHXGFC0{{TdbXh z1BkxWkbLHQX*~j*t#7tNAQZR)kS)?&6${(RmeFL$`@05ICy8Z#^?}84gu!64p+lO- zftOI5!yYg>1yWPygXCOrEKg&;@1|VFh}MdMBj^DqS+7lTSj-Z04rrHGOB2Z|(DVW~ zR4jk%6?j3G!i><6S3(jrwPv?nI?A@16sr!A+M4cwyi@AS3_ud&J z3&&3k54rTk9@Knv7Z)kr5-ai-?~y#9_)+1~9%MDV38PBxrpkq=A;u{`&8S?gb65s& z2{DF;cUu&-lTDaXPLM*jM&H~QV>gdxjgcXnr?~8k_kq``2{Y7be>`m4_Q4Z=b%f@{ zAQuf{_^vca2Qv$tvrN(RPeUU;^eYr-T;V?oRc5R5vw;Of{+!g1RVE6bzYL6pZztnMJx@-210N#q+ z!5sZeOYA2fqPo@hlU1Z$7&@{=KBz1+mB>cME^!p65sJ?fD}JmA6UqWE_3>El+)=|; zV>bCd9=k(k&DzMk+y{@JIWq*&XT&MjMX6^Xs#G>Z@+V`v7$w*=w@=W*vxzc4F-BD+ z9iwtPZcEjQ5)3o({vFLU-W|#=f3E`rhl3?n0l^D%^`EK}cQ&`U8dKOR4*90}#wJcS zrNgB=ub$s!?RYK4p(D+DTG%)*3HG8M6CJB$84l~8*vB#y>6z{>#Kq@UR!8-m2-vNW zSae@+EYa&~(!o6JdF4ZU{L%ggcZT~$OZzE1=+xWP=gc`hfpberwfa5?$KN!joLs%T zZ(HK_S}rU$d%s{~nsHOF6{TqC<(sYRQf5nJ)&^MF9%ns%D7c-mY)glzuYJX;Cq(AZ zCSL8_TEWWLKyvUMFsYM1Y7;Bo00Rion)exK)2Cu1A za`6$uvzo?;z|E#NYwD_Bs$bu@)%h{IKFW=0qdPNmMfz=7SGxVQBnzQV91t4RN^*)m z2EQXDAUBAEMrUMA+V15W*R|)2a`xbk5WU^`1+#BU573G#N}u|z&P7*`UkJ`jLchhA~vwG_G-JYru%B$&Qi9$A&Nes7e_@bkkfFy2TI( zwhjU8KJzA!LyT=l#$(hGCgQDv0q|iA&atZBp<)sHyS01hGMt|{(<>QYImr!HVcK!y zBq+VrKNxMVc3ms-oazytePF192c7-7rsCSA>E;IoCz?KZT%)rh8p9inmJuKbi2`NN zCP&0tN|TjT8B(?5r_UA(3|=vJn{OH0MOaFXA31>EX`9108c#0<5VkFj!Dr?TjLbYy zF6!#Ncs#+lrReiiil@iLp+_{m5INlt1353n+;T@d+bL~4y^i&P1LCxgCSv&xo=qG= z3*1a5aUx;f2+fouS_*?D`DE3Rt}@k!^`?}Y<&6E4WQAJydWmT0Jfshkof3|w+_&-H zo4gWuaOaBI!8h-=l+WiJpZWSeoqL6R5nQa4vuIBK3(BQK+5re>nXT+=KffZl_rM<~ zk0e7nvOw@DVF2vE23KJ3Dm`MeQs|gfFC7PqeQ1(SHpc84A;!8_)ug&Sk%qLHqk_UZ%JZanqs8&?<+_35@1Rbw@zady zhcxgWFsOjLOi%yi`CouJT3k1dtU{d6wU^0)^9)+hrDi5k-!m3f%awuxy>~bG*2f$Q z7|pty^1AnHWzrV9hdr*@-76*e3us?7okM;_GB<;IWeE_yU%kfPAajX_TftK^teOL#H~ zFH#f3sLc<*jaU^~mEqK3cbe2s(D^LR=c67M09lv|=_tuqpWqYKtkicpeZ{yRXVHqA zQ&}|q^LR5-zDOpF{efeK9;YBUd`B2`h<2AUdQXWXPw|Dbj|uGrv0_(s1Y!4dI?D!} z-Qc+%#ztFJzuPPHu%)yNl)Wge*z%1k}YZ;wHx4px`k({f`oxN4j_w_n!i+ zQ$~AZ!DRc8bH7-gPy|)AVq_MK1o;;}b7tfqw{e*KbbpJhK)tf);+fUH)uP~}I_DPG z;?7;{(t(lgTD(VJyKsa(&v9PeTx|B=TAcp-V*hnZWW6pZyd<9iqtH2&sRh&%)c*yz zFFo;Bkc0fb2YHz(QeuEyZHmQpbqNtN%9Uy7!(*x~aKAwD$}zud^i<1UZE@-~cg%?gIsQd5(h#VmokG*Tniz zC-_uO;P-NWN-Z@}tQN>!h(@f1DhtGy1P5yF4JQNbB`U0J=})o@N#|oo*rg;jN~_0F zKk^o;=O>LJFmQRcFJ#xOc3(A4Rk-AKG;jCiBkF^tR<^c67B?Z%<2f^BDmbzQyc1H| zg*YKFxsCM2uq|6W^n{gMSj@s0CYB>NUxqJu3CiP_k;!qq-*AIZst_w!_m((N`Xh?D-g0z9dw@#+rJf7k$XYXFr98XE0mmjG1B+zh3jc<9x@qqZQq+TmPc@ z;@gq-<77g41tDR1PvgZa93C0u8BHJ;*d|67L+(N=sI~}eQp?!JPbwD#y^1~Td zOAJeFQ_Pv(G2%HRtn~;T3dS2x>lx45hAAljY`!g{vO>K5^({{2Hy^H>2J`x91q$gGLzwSkTkR~?_jno zUtn}E8OVRK)2GcE;rEZZRZ<;H8MLC$ULLqr+4lP(=)9!I**nYfj@K#|47gD1501Q9 z#gtB$kqgPa6#g|zOPnEX6EQ-l2>I|}AjmbhgP`2P6Mn^3ZyjjyX5pGyLt+aQi^Fzq z$LvDv152|P)Uwn_5kPE=qyts)7JwqzN}RbTf8tDiFX1kvd`rWh%BK_)E}l#-%f`w>HaR=fXE_0z$^ZWC4yF+e(Qh?+f$(h&VumwSk#N z`kTES*%`>YVvDCxkTda`OIWE-v7`69wGG?u_usS)vUZBFHI({y@NGp~r7Vmbb2JWF z^J7gLHHKQ9+`^O_hL9KOU~yD=Noics!6bS_kzaV)+{z7v4(WvHaDV(Io`cFnS7WB5 zvPyJxb~%@`gL6Dv*6Xbdac(+!|AVj5r9e)x%T|k#Y3ntB$wL5>imC-4%y|wunoFtr z@RI*ccn-n}RFF5An~jj0#SW4j=|SR(RnO8|wLUNu1n?Z|#m4-?`#2vO?&tExm3Xm> z!TjaAY>Nn2s=cylz$2wtZfEG(7q;hF@^QkC{*Qg$sM=lgAI2-t=OtuYDqzIt|B}3B zlB!4-5Njr$%WBm8viZ&KVCzc9xBu)9K=tyV&w^%o`0FqV;0!0mjeb(*T1VJZW@OVBcgaDZC$4INV~? zfKcGa#x!X2A~3sfWaB=g3$wX3b(`xv6VMID{fPaUXYZcZQXgMFQfg(be~#dFMfxSR z9{*#FMd|@@-S&hPUI*_*AlB71+W{zk=8R#EYdz6bq~?Zz3Lf% zwstkc<2|9eviLk3ht)M|%%-X5;5IA|=gVPG+L%UDuf?wqo-C-&vcoaoz9Hi&kVdRn zL7AH@mRII=&8g*)dl;J_>Q0Db3uddMX?o^bT#3G@l_4)kZ*d^BzKh6#Vu73?lN+XI zzS2*Z*)ph|G2P<&ENW!DQ*ZobeRWMm7}38w=g_xe|CDasBBdoPeV7VfrRn{Ms$eCN zzAy+Mlin(tuH(#pFCiW74eo@ux?K46W)? zj+G?KPQSYnu>H}s{Z7-kq;mm}`#zrtj+74o)aRw>kD}676uu`1(vEGW4T_o(GLnY~ zS>hZ+`!kVphCgwGa+R`)^fNFJQf+cT*_>gc{4afC+d_>=cD{Q?Z@0(inYumM+JXa> zq9J-u0Nt#*_Fk3o`MM)fF1+vMJ`UFG*)$=iq<#^35IH&wncIWc*nKMU&cv({dgInG&S7gjtaBdIMXhNNh-Ic4p$l zKmeUW3hWncrnH+;@yKcu5NkpECuU~^Cc=wQ;1d!WY8qt@;zlcK^Tg(Y4N1%r8*rGy zwoe}7ompzsZZXYHF2|{iWaZk1m0{U>(PHAQM zsMpE9xn4x)HujG-aYl`>HaB+)zFS{!Stg?Mz;q7>Ro~c;4=7;9Yzk=K(SFLwzagZa zZIW1jp@ua~{#~3Y$u@^`DMQLq8K4o`&fx>}(=F*i$boML00LwM@df+=dl|ebi%Yvn zhK~^4T?8v}bbC*g8TXH*Lq)_)=WconcL8KVxZx=l2fF3Rr|0FnV~g004~q-XeWB#|oSgj^ZJ__XtLOhK7)UmK4Q*S1bhh8&GsgnzM-$CP zDG4Mz--b(RN5#NFb){p0EpIQVy{)GQ7V{ibFNqpauBwJE)QLLC$M`iMq2F>K9S3He z&^EahS*491?r(M*?G9P}B@&V3VP zZY-$o7tUxd=ARi*4wdup_=TpS^QfYtFor#{H?%YG@Y(iq&A0+p>IbS=;g(PgrGjHl z_yj8FX9B^~M3bfn8UP4vOdMO-CV*_@Q7?ygB#f}nYS^g!o&EcT3Vx4VTYQ3kE_Jy`B;uHLh^<$EC@U6rJG~YcsgrWj@jace2V?g}q=cb&k@o_KEE_}4F zdpVwFIGJw}YSlA%{<8!1Nd8PB+o9ArZNL}rK61T!oA@PAl^cByYy~w~#6uMDGkMzW zLWW=>c6kHK{6aoazDcSl=%d{xgefc4314#O_Ai`tuyMR+#3;|jva|DOQzm}G@P}!* z;Ka?>ugbS}-}?Gs8J(Y5TWZHCUV*=&uw_QO=1%ZAXP{a>oVPtzpuv^WHHE^A`GkS9 zjdTg^VZc%r&Zc*+%&2So%ypb0EG%bcH6XLpqb(3`D8wqhhwV4IJ$6p#tiMyF`v2eI762Fe&m>7WAPM3@$T1CM<)!!ka zVvucLfZcd-R^LuPFKE4;)9FihD(vNS?%y5TD4F7-_J5ZE|Cd1HJy5a8 zjNHXhyV@OqFd@l6Cj?1jEl!vg?i;BN$U#u8hpIP+SXW0n>M3EA{W9vOocs+gU0xA< zs+J-4yCwdiY0Q7H<-tC)pys1BpS#c17O*TVPlND6){kuyYkndh3qqJ`*`qC|KL)Gq zY#y-du69thqbGFO_ZTMXw;wzlJbcWdGD^lwM&|fFdKEoJH-eZKWB7|gimhhZ!+5=& z_POSFc*(OJB4hC%eM>*q>>yz!+0sp7%s_RPq2H=ot-ywhywN}@oyz#7E_(^y8ZM;+C+3DiufW_OI!iL<;TD-Fb!Sdr0YTIOn4M?o= zro7bo6R}J6vhpWC8d@M&w%vvf%6~oSui!~_npGpzOzc^|{}%P31yvQLYHxP_a&2wG zaqrV>v6?A%Z~RgQ^30oj!v)9_cKzj!3 zAWREGhF^FmK+lk{4MLq}k<7S~1AVr-_`*rH6+Ju4dyVFO+45?qDBGbFtcqsJb6c(F zcJJn`3yTY;GR8A0c{q=d7+Svn!*nH;?6eXO^t4Jqo_DCcWrz>OJ9JM??e+AZ>%rCy zRJhkEUwutOcgIQgs)f7v1T~ggNu5pPr?zqURIxtjKdcp72qS``)`lktYTNUlcG+9D3;{PaqS ze|cc>g^}SQFIz*CV;VPdHt73oK7?C1Sb-1i9~dZ}l7dm;7;`*Vf^G(9>-a6+!q%Do zYuHtQt3c&rSAVRDT`t{HIsR#yZCpwSE%G6(Y9=cUsM^(M$lPf>pk{xjXD(oN zDYJMEf8b@$?ANGf9@_qbR_*ng+d0>~9UrTWZEjm}vR%d0-X9^kLR$QwvBDeKicmMd zio4K8*=}{@WolK66-8Zh?zFK~; z-M%`7@@O2ng?X7e2phGo+!PNGnC}6u6rl#?cF(J`+Q_>hJQodD8kAI=xbz~4)u!<) zWrs)8;bRW#(dg+TLvdO}w|(*oT5l3{{s_Ih53CJl;q$6YD`PjGlW1;H4%xIL;2*_c zMt0{^Xq|SP_z2JQK#M0|$jqH~Tfjb@QW?2Zf*!`!RismJhaV2qDEG72p6J*7E`|H` zhh(sZEZd?yl*_=?Bp4U-ig1&;ZjPR55QW)@kQb{}2^55(UVEz{cm7N>9EPV4WtpDf zvF45bG}p?TlJgJx)D{w=_PDm#{9*U!5BHuQ?%B9u*D2*McfBLOU(TbTHN)FBY*<4~ zZpRE32_q!Azt0{fn~@ZtOM(D3?e{9?*+{`AmGI z2pjG@w4gMyp{_w>z}8pVeERwEc;jg6BMH@)b8D;5+0R>>w9#(DHy|wh?h%8=2+aV` zs}yWz>%n{H0NCw@*SGbvL*C(KLkeXBnwP7GYPOaHl&Or2J{=mzzkYHKY@g%p_M$h) z_oE0oay#WY=9R@cJ<4du>@eS%TN}R@{UEjtp#TMP@yFUKtwQ(Q``iRi$YY`6+}M6T z50z_F?$!SMS`c>G#7C=5#f4jTX%}N!=f@iIL{G00sZ)RiL&^6MM#M)AH~~R;1(Fk} zwja%;R713OxQzMk3MfUQxBoo;x8CJ;4xwW z*@%vkwnL#~_!T|S>fK5*;#b_KO_hepMa|2~yVS6h7EV^by!~fURkzQx>WBNg8?SAv&KS!XXllB zwn2M#n@;Sp{-Crwf6Zcjjq`pVvWo`X9J>>L-1Hi}-9N<`Uh{HoE8X86q!HIO0Oj}A2dShI$t!+&R2yK@o) zBWdIiEq{Gk=OQPmSsXZ3S(zaGe($pVOr^!=mj^Cn#cL_MjAl{rXQweWl({>61L;-+(P<)j%vr3+BEunHp=YI}l#Kk)1HncE zm|PqcJPixrVif$nbouk?A!DAp7YE9hEPNU)&BUng2D8y}gNrpOux-dyNUX(^fn)tM=z25J8%<#-nG1aMbAXH*rNXPUn-}glf7M#o=jE*Zif~}mID>G&^U7|pFB@uy3IhtCQ6}6j8qf41th>FzAbO^ z41|nFf%_q}wF>2Cu#QvFZky~Qk}q@bXFsDGt_%$u;cVy2X;uN1CY ztO==3xdh)W?MH54=!hK#%p=1@&SK@B;00Bv$c^7Pt0bfm#u|4_)!j@!9bB7wA+<$% zw6{SSmjmUw3CxDPh__Jvcq7g7IbZLt*y@%O#oZwqhX4ku6xWHKxH{$=IUo5>bVAw- zqG;w|mGCD?DPU*$WZB~Wk!a@7J0YO8!f&gr#F0=17(eE&<#e`exBO*&5Yl{`C&OsAkUZ@F08GR6%z5b(EmutXY--?uJ!1#I>K$%W>3aE6! z8iII4oqx_@hKckPh2MHmv%Y)B8 zjAG+5;mFYUPeRx&CY(v&4BCKc34W$fPg3?{jURr!Fb}#ULWz+A)LnDcF z4h0u|1#scTE40Q&2tW;_H#U z->}5NCGj+yRATJEP*hM}(xLC$JYjkURq4AFU1^?`HLPMjn-qNQf3|m!r4}8dM zY5R!QU-)I*LIS0l7De7K-X$p_A0R5Xkj*5Is^Kx}@a_g({yS@dG{f8hjAY0{4}GXW zcB`(3WFRRQBGruZa;9lKPnGvLH}-gZm{!)CLQcGMR(L>`t;6x&6vvE&YUlnp^GnRe zyt@8L(Ta4d8fZ+jDfZAyt{x1W2~kmG@X9FUU=n82XMYohi9nBYyTM8T3SQ)6QD0NW z>{$(Jg8eWUb_X#~BV$AlLD>jpd!8GfHL|cgpRqDmqavH&m2O-%@jksKdKWs>*I1(E zL$HzBzh{mnA!|e1sBFs)4xKtH5O|Mi#~`tOOy6WVzn$WvlDvjvTr-1>l;&PCCGmr?*3qA`?I&8p)5~YPZAL zG&jjD=`QjB!VHQnAf~qgE_)hx&b`eTVJw)%tY4Zr@FGTa7}>=5xf*iH1-0|)moNI4 z@Ty({yP;3SQoD~DrTUB_%^8=}ueZH-z0E67NpknMTS?b`vsk!d+c^6Nm5!WU8Rgsn z7hWq;B)>0q7v{2Vdb%;8sc#opH(!Dced4XqF z65;^qcfs~b0=Irx|3mw<-ujkV^UnQv6$_b`)f@G5-COe&6b?DZny0$ve_2ksoqp_E zRYU%8Lwef%S*kqqN|z#;qq6A+FnrozQ5$tLLVgNPUzo*@B5z^jgQ<5po97XSW~j1c zWn#*^R`vbV3lLJVg85`pi6b{_*rn#r+)htKx;;m2^=BL9nCd`t%85MUg7(j@hmj%my?l5C@IIV%;(d3o1OIO-){keAgO! znW=s0jFMFGW0~Q>5C^w2eHy9fdNrP*>n9Qw)u*u+6kTp;P9=P`C0t39C??g+4;ttN z;MMKp&P|Wtd>{7kaAr?ai0lI??D^rb7xWjuwB@{rIx`;i%k$II(`9R^T{btg!D^35 z+gQ*9SBVOUP?3Bm)H)84dA3)oB)%?ScBrYgAWT@*!)`Kx*aG5*fp*5vtdK{BLmO&r z3t1b=+%nusjcKy6cSH2_XYA0Sd5gyf`is4Ebe=QoO*AvSLc!ce6Qh7S2)u@dz}ZQX zN+D3Tko(Ac`LVYdM&KVUNlpeyB=;O>-JntOM$-NPL+TFbR{Mx7&fYA7n~&)%BF?m$ zc(e&KbG#ZKn_3m7=6gU1s}W9-Ya`w7Ik&tU>~~dhE}QRR>lqL5mhB7DKA6060vEo{ z*dy)YY^Pi{SV!)nY%y1*i7i;>TKsP<)S5*Q0!Pq@Xe-EP^j#@hcIT}4NI$o488_@< zAUoxTPZ6I?d|l#WQR6*dAnSGjsow2tJjsDgrVW^5jK7iabE&3 z+*jc2(00&wcA`KB+&k>`_J~n@gIU37B*6;$Cb&rlbl5xecoF5Q&Q&i3Yxx>8Y{#;R z){MvC*vAY4REMyj2#X029mZ{FWXJ{ke0V(UFJF5!%KzGmTg}M8%$I6YB%301hQ15r zrCWzY8>Fo4?R;fn$E$@X=~_X5yujeEyFVZv1K#5{4(LwM;@#MIpda8-6jw&VltmU& zc3`(m_^E6xCBWD#sKd4!-ks9UQ?mXWpMut&2othX>%LSVyvgEXO1$4}nr~*?GTJW^1C!`ATYY zx(YLX+3e+L&td(C^Ua=n?F@Gt+Rv2#+C79m-`SI;lcv4(Y`IEuMrWJd(fWW7?ksl* zkB_XN47v+n11ATN?!tF`WGnIpvI^Of%$6COzf=54d>qmhnL?CT*&9=B__L;WL&<7< zYAZ4>z8pKUS%9c7G#V*Z$_h8~E|_Bb%fvUFeCnU^b-5w~8|+?HGUJHfn2{m=01CGAJBuN|->`}l|-vmP_k~^gGkhi2%WCanLIO~?maa@l002TH-xs5W) zQJ6AKj^7KuZ|ymO5A|jRvZ`#ZD6_L#V8|c&eQ{Q^F75sBurRi+@T??OszTZW1%c*NY$5|Dz6|N{XmNE0VlC-<&_V*553t(| z)tT^3aRxuuR5v*D66J0Cm{rTT`UuqXN%z&Pubf8{gXqsg8t-#CUtGh39v^(#K7Z_1 z3ShFiFc0|H6Ui(vmADB2F1nyY9f0Xr)lw4204aHs6+@A94y5$3%|wl+Y%?I?z-c}z zmKEsV%z@B0DMWz1NC+nv=bij%K)R=&e%?q;yCoyRlE9N#hxRXJc`kqe`C(&Rmg$`x z(-8;z@8+gBv|Tey5qSg?0+^Ii04}0jfw2chF>`66KvIAtkD&;`xg)m(ypC5YvA5t{ zTAX;_Q)s7IX+)O&xnA>qT<~uFS^`8?A#s1dl+_YA4QTW@vFYeYV+Xsp8xy8njQbK= zSjAiEKF6OHFAk-Z0xZtbkV^%5(dF;p;$Ngp{-;Duq%mL7KJt5G_#S;GRu^-Vx_v+N zHFVJe@SckB^kO0a^C0-X9W*6(=p3uS(Sw!G=^&XGqd z9=i1!gDsiV6!RZzI`NT_;U@JS7mGx{kO5j05J8|qxrsJoV6!K0CfW6ws|sI;P0IYc zF`s6_Ly~g#e4I8t)E{g%r|Z(lAJ0#hm$h#(jUML2(l_4E{`PCOW!;@>`69=Hm%IXe zCdadHz-GvMGEvpK$J{I*>jmda(+Vd&wnrC!nq(h{&pXea%CJt%$3CpQfUR>&D;%`i z@Q_+KB|K}1_4dYYGp>2~tc^fW2(*rq!=kNnJv8f7T>gQ^`QMT9Kk$+Mhx`|x|G+J_ zW$qg$!^m&fzgh0)GirY85s?`Cnjp3I9N+ax#YXStY9)({ha?9T2SQfvQJPQYQa+*` zeyn*lgOQs3;u(qwhe2lyQL8doCZq;N4LbZ}DrOc={>ADM|6|QbJQyulUrvGM)`kp6 zP9nK`yOEQ6g#h&#LIWdfPxR|)jhn=pD%z3_)g1A5`j0hZ)f>Q#o&e8w>-3K`PinyE z%FTYJ`1*~ydBzf)f6tG)q{O1|O$UCgN&2YlIWPirD`e%RQ9wLulLsgXu-DDhi9Y`Q zoPU4MzxU_gcJ%kT^!NGsw?Fz{<~OrtG4?M5)fhRxX4&zw?{}I=7E_K$4*s^q?Ztd zgh(inK8i>QMS>6#6r=6PVw zlXlPFy0P0X`udLVxjzlWzyO2yMOFNq`T97ExSx-=Y}o$GF1cx>*ID1kT269x!Mrn7 zemuQXNSn7`UKsB?+*!>(QhPel?B3%$sq5;NV-O7Vk??K5Xcs)a-1isu%%hQh|J{V| zJ%t_nS$181Wm_!mBagmX{}8kL!7san^eC2@e@Jre2lJ)9b&q6dFFZd5oF*(zaDLDV zZL72qC#Tr0`-wCp8CMg-j$By>zGT+@@SDuj_5YA1{=cU4`>&8vSg$|hbT9Ry_d*S$ z(-V_@?N)&F!g%{17pBnk3wLr3eLXeT_PZyqP)b{LD)o=8*%;}*yP{XQ@5RPvIcmWr zX%9xOB){6d?$xHxLGB;DSbx_s`J>^b0D6Z-FFHn3i)eK!(x?mM&!iXPb{tT>(iLwe}X`Q?CLh;zU@ zVeCnJ>4N|E9h-2$<+@#N*uq&X(^4Ky6%nT7s8yHo$` z;JZN$K8N^>fADlGLlOVy&-fAP3$S{rYa8mmF?w>t|K04c+69W@ctr{R^Y?XYnCE|2 zmnjdG7Td&slilR{S0?kryLrYJFz~w+ssU*3b?5&!WBKP-`Tx7u>4$gkzpwi<$oKm? z@;q8%f(+jhCc&QyKmX5e)th1X)BsEbMEKTXn4gvYAGS7|jqrnvzVGX_f7yit_=n$r z1%F-w=;5wv%UeRf;&aVD|HG8(-$9e~hkIPuw@om>MC<>)Zdq{YmwdMAw?eluiDRtH z7v-(_e>K9^=Z)Y$bxB)U=F+@tWq(_ee}0|+`wnLR?EhS!2j1o1-vLNFVwk-aJn(tP z_?k5NbJ>5nQ$Ij6e7#l}Rfd;QEItSI#EQbP*CE5A4$&!GA5p$hjo-$B$JzXNl7rt2 zP#WeP3>C2zfBex}X{uBODs0c!842TASw&c*+AXR}YW&6#u|UHad<}2+F-kH~acmqA z))E*;%Q{ZHwsSGS)J^0xm&lIr~@u|6kDu=zp5y`pzwkhxqRgSqUaB}xOtDeSKh!t%Ewoe+JB}kREm7CJ0!Kzoz8;zNws8C_zsLJ z&^4P-%s4mHXkCT5`WZ#nsm{G!<|}W0ky_hy$aWL?^6Q&>e|EeQnBHwSX_!7cnC|`c z__!a*gX&*8@JJQhPcm;AHEiB(zNPR_J|R_ngAZ%BC`}eyPNHFR?5$$khzjV|1^(c0 zvr)fEkA~Oa!2;?q?;!Bp zTx1Ch+>NTrf1ltRG6qZg@OyrF{rRtq^4NHk^df%2un<2x{N`^4Cib@fKXxvc{YybS zG;g@DY@9W_7MtEU5=9%KZTA@+WsP+X^xlfNW!WX))VSTi!DN7LzdPjJLdBM+TMVm1 zmkcKxDES(dzGatR*45W#>d{`(9;==XiVJ>Rn6oP&@Zo`gs}9>UGgE#K{xM|Te_nP9 zkzLZ07HkRL7e8C*^wcS8eogz?KPoN%XRMW(fr)p_NS&EoY+)3mu2f0^h@dqz{z1Cp z9gs)8VXWP>ZySc~0@y^D90o5emXNLiF;9F#z7jvG4L+tPdy@}bA*AI0Aowt$*`Fh?+c_-iq6ei|xgPF;$1kSFKA6Zc2>%?| zb51|gy2>rx@xjOPKsh_-eMO{w3yj9x&#}D~;+rFIq${MW*uhShYC~RJVq8uafe{Fx zoT}1!4lOO?ydV06vw16fn~8?yV74!R>23syC)X~t@Svqy=~W`2fa5QRtqxQN(<_mY zar{%2L0?U0ZWSCj`jWOqRK4nBI;0mw@AorVh}|yI#J?`Yb;E>V@D1>l3z*AE4J$@O zK1T|!%-Q{G77v01?tu6dDXFva5}9E)KwXo0GSV&I*NM*IhK6$(JiRG|a<^dpB%yWu zWS5p&-=dLt7yqjRS|-G&xFo*9K9oFaUua9Zh~!--XyuWS*_%{+i*FwwTLuH|o$4q1 zGSxGU&At_Ake-q1=0?5|`?7&znsg9O^%5(A0t6xeTWmCUWZ}5zbOslA3hQym?TAgm z>T2o6#$qKB%Hn+U7C}^EV<4w|p{h!%Gi$bKzAgGmmg)|li3tedk$YC!MK~KLxF*UY z4Fb8XoXi7rgI69#ha<_<{xw(*td=2G#tVU4O4JJMCmrP^5>kU`+ww{6CEt-(pb?K5f^-+;bU4C0wFZl;Mka_ zWa}RP;@j?N8cF)oRSR^>o0TME`igYkl8^?c$cUA-xp1+HXbQhzD>{n3J%Cfk!m}rh z6BH5vId5c}zWKWn1Or(;XTWQ}}sA zn3bKCeZ=;bQZyyNuC%7WC$hoA$EgRf1B2?tfGiCFuc?v@Mquw2pnZ$miyLbG5$Xb| zL5=v3fZVA#YOy-m8`o%D0O7$82@%e+Z@L`&8l#@hzLye6S*QJ=H%HC!^T7021B*8d>rY$;Hb}<7viYO2Tr$zWUWQkzKpG@M6k! zOpddfibtYZrCeGnNS1`J09l;86*|&FtOZnbr!7`0K{4jyJ+Lbb{@W5mSC65@q_PQb zO&dd-HZPj9>eyML<4dN`NXZ?~VxL0^=AK3o`+#!wzK3@`=%G!#Z=qrK!t3Dp$78*q zJtDNU_xrk9bSfUbbQjNeQ;dUAUN`Y6S{D55M6n9TRST;D{ZSmy&x_DNYzhGeIl(sC zL+Egl&1=(flv|9*H~oa)-ZA@^{EtG`=izK>g6u%L_wnI$Os`W>MjAb|zjf$O;`CnU`jRnSSOL8q_G0^ldPO@3w z&$MGEeDFUkIy`5wbkDRYNQAbJf2Dp!-KB^)W>IBclJZu$a_)myLBancif`X z{xi1x_}jmtZ35dN29ut+-=(dHT0*EsoN#{5OP7l=oTE(XS_-d{V1*oOgb!cdx+ZVy1rUVb4(W zpz2P&HX@|&Dpn$Ld+#l?H;Qc}RCtgzz9V{Q&`jMJyfK_0%q_Fi zq`9)}L;V)?rBcbW#i%`d6W(*5JYV5f&z^S(`{titH@e}5_w5Eds@X*MV_k_ciWoht z%lYSf`~Mk?|Ig{pJN@?y%n~LUTcOlWoBe}N`vI%WTFy&go=lC&%p_4ra>s!vg)_qK zrMGrgWL%dk^(8&?Qp$xhH-5fvjyj* zkXpatoI^Q0nSxRd==(62(-|L7a>2gqh`(QpET9v|@696yz^XuTOMD=0wr5M_0ZFiV zFBD)WpaF)m3WV;mkr$|xj!_gGX)(B_U?5!Nqrbkhe@O zdlw}?$Bdsab9T_pK`t=q_#-9%k-5l#S8+EZ1bzom8(F|Fb%Oe*URtTe3TRw~$NUCP zky7x)o*}TYKM6{z`5l2JuXW>#<{o?&rknN@nX3=itwp9@Sp|9|p@W9Qzr5NTu}8r_ zC@iR3Q;YnGR@t}qV_fThU^o7%T$S44U$(+mzOO3;p`Y9Ow=~nPn6~z4P4VOYUDkh5 z$7C$4zpv{iND?S$iN)yOdusnt9AbiaaKTN{q|5?SbW)6AnxGKd=MWpDo3K7meJK>Z zHiy#Cj1+MgK=EM8z*+r^aN<~LEpw$ulubuO0Rqn}53L)|AX0&ag2S zZk%eP>4)_eT>TBG=g1eoD=4ZfFNAdG`a)E%BSxKXp{8&5+ed}H`_1w3a?qUu=P$j= z&v-Eoww6(~4?dmzx#K*+)Jppa8rAip!F>^@*iL=YEliGrkWrKXYu zMsV*oe4OUYP5e^nT6xJ!5ZNS8XSAFo|pmM%%cf*!p`~$-x!YZ{1YsFvG4>Npi zR__~QiNdtcv~iK#fCKLCj)r>g9!7<%`MAOD=GQ;{$D8s0-dTt1!>if_Y9*%0iV?udNhAXP)eHL`8R-Cp2D>TJRfJwX7() zuevoE@u3HE+oXHVeKLor-OEG8cFIT>mD_VJANb7ifhF6DTBhHs&u&VkXI}K+jBV=^ zUOrG;+XkHk5;efeG+W-NPz?aoMrGK z2EC&+;d;ReIlSXUm=>UGW*l<#A)X)kg2$*EIjvMRfJrIHP6(T3{`&I%dG(rEhoU)EzEkWo_FNVkWjgTbYVR%w^T1y-Fe4E%d-bOb@))biYZuZ`&74 zR6CuR$YqM1i$j!>jl-LQ+?dLHQ_GBkYG2m8tT!a3$5O0wD{`+pG?_CafD4b{U$O(;GI2zxiswE6zxkPpiXucumaja;yn&4IDL3Zn$23;k#j z0twr(3P);oG9NsI&vQEe8yq}6Jk6oE@7*U}foknQ5^ zT*z^-vd44Vn_jpou#gj|5X0MBQ(lKo_o~xQKJ(bKImTY68^vxC(qfk3dW{A^4}3eW zHD8YAB@I5R(>5t9uFSw z_j?_(@YeHi2GaCsDWzD$R?LjPJ?2seztKN%%0WBg;V~6I&7FrWe%@N0R#a(lV59er z%|FGb*q`Hj@j!yJQCsqu@vFRE>sRcxp+=`FOhe}qs6g0q(%nciplfuGJUZrBH=^EX z;Zjf)Y;iTO&^B^5P^*wMZ*j#UVKp}pl-t36EdP^X1NG@X%b&+`cuj>WAXCv7|upVvF#msP-J2 zQX}FeJz?6~$+@ijy%wjueBK0;ir%v)e9~pJ_U3tV>kAFPU9Do5kg&9QREU>^grBU& z*RU5d1m|ql&*j*6ETt27yLGb94dGO=Kk!YojtcY=dE}~}hD@foyG*TbwMF}pI)vFb zR7-Ngi1-SWD*am4T4F&7%LjoRnAmbr|1y%9ty2tCB@U{v2IkhPb5DDuc+U1W9f4e;792<~MNt<7ELbZiiNYfH zQ?=5W0qRC3)x7rLTU@@|)zSrPupI?A3!SucYEbe8AV%Nm>{53tIQ~l5~a10v>|3=BXd^8MSLnUc@4K6p-FHq(7 zMCK&s;gQ#XOPxo-1@leI?LQSw)h6f!aqv?gvsFcLn9o$#Kt|MaRA`i(3;pf|BXDQ}Q%b$`aX9 z2d}GMz188K_QdVU2b|IAaRYQDYi#kW4J65cUxVF&)iGL8_%y~3Rvx-doEznS!O_#i zicy<%E_ySR(kT~H*|WaG!ernyE3#0&c)WPQ?WFZYE0a}Kf@?ATq<#T%I++gIW=S&?5|`{`*YUeM^^^iGii_9ZXnD?*t7tU zU7=tsd!d1(6zoGbW0#FNhR~i5hf+oRq1@IrTUuHePPXa(13`dmzM>Z7(`v2X?SzAsu9ujHeTMh#fy6ca)Rwk~WxD^5XtFSs`@h<2AS0dA5u|PL&lPGx)8%FeQ z#o7xt4pX`EM$9gY@9Q2!-~$RFyzSsJmC5_09??lC9qmG{cU*GMCk47Bm^$TKy*~Q7 zNHWMmHZ9f(|OSIT7FQm=RVBR$B?IB#!~<79>$dtRjeaCvukV90ZrK3PkLP zR!q8P+^mB+@ot`LmQgs5TQ>+U_p!&O#Z3c7XG4S;9Z$Qi>Y+SBoeS;}UI_0W!KUcD zX8P4-vPL{`%`vdzd|63JvodB$cx3>N3N`Sc*Fu&RV(sjyGpzfS@>S|3_c$8H^1WPO z1LsSjHZ|2yhsBnmNc<(z`>{E%NFlwNcpIg%(td-~M%IpSGa^z%R*h1m&!QAnKEr;Y z#w+K~2){y>w*=iB;AeaQW7)DDVtDhz^1iQ=^RnePCsfRjM9Wt{wkfU*uA5L5WTzX3 znd}c+(e3Zxb*vOERU&gpWt7oi-AB=~nchPLlk*Ronm%UoSUsO(6OKRq8_Vxj9sJ9# z;qU9_*T%lDb5{5J(U$?hBL5Q<1Kb=xnMG6mitB}KFHFP)K4c2pBoxx(RLc1Wyf6)6 zHuNC!`Nh45g0F(U7b-L5m+H{PpZ+k;K6tHX>C2%4zLT`s1AsyvT35C*o)Z@eC%>;t z1Ba5g9@vrgp``}%%?C!TLPNQ(N)z)qV=5n=B0h(s_og)3@_XBG`v+Iha^gcHjUMD& z#x@MmpRbk9k)RPnD~2bgJO;y_J^m@V;eD}VP6knbI<%po!MyT@%ba18uY=jD1sTX} zJ8KBR!LPjmvA?gY=x$#&94VW_E8r)yr4QSL;Iw7fNwVMzA8?!Tb2a=9#i%)DARDU4 zxBtG*!M=Ym75)hRUItL^RimU^=K0-Rph~_ToN!C5iohI{?w!Uv#GcX#fgbMw-|}P= zjd+m{)PAiFn|!{u3{te3&f#(-N5gk8D>PdxVxiwby~-gcGS<~5rQ=*`%Cn*;PpW4& z(w)9F5(a@*i&4E#yWgT+lX=)-`4Nz)TP_!d|cZYNv!5dz$$>>Q^!(=L zmR_iV^_r%xI-p~Ya2ZKN{uvlcL%O9!;3~9%*diq;a(*gw0VkKrfdMa$FE9%?(9yiHW7qV=h7N^8h=T-n24APFyY?3N@88;dk93$x}P-lcr*Zqneh!97*5O zmw9a9;@Zt&FQ=TfuSQq1M5z9#pcJf2lcdxH& zm7o#-)YeFtN~4NiVzcaLb#~k`TkV6BRvrhv-4+iI(c{*<@SP)8J7PoxanL`t%Nw*y1d>aXEPzl8Fa>VQ(4kg>7( zCv1SESbP##W4KfTi4SoqqcE~`l@Ci6JD~$gP(Ho!D~PT0o=jI*^0jcM zal0>uIv-O<#}OOtX7J)eviWZLg7TMcDZM4XkRzBM7B z>f@56R=Qp7KDQIy2hUNSAG{aw6+Ai0!cF)`kP60az-9JAa8|Z6um4CtezFqwJgU8y zh47Q)z=L~#%h!N{1nZ~F7f4f<<5v~qfwS|$@OrU~AiHI4v5?cvJK4I{Gfio8tfLPY ziEWI+%T{!2DZvrxSEmiVT!%;|S--p9;O>7@SbB7Sy?fNBEa2e?Z&>T&;IFzSG3tWa zU0Lq0{C|ePFW&G;a-VStkd6_G3rogUXEQEfwV?(JAVAAtV={D2zUd(OK@f z%IchEiOy4KiM`G-^9{air3r^poqMI^$^H5@IX4R(AE|=fC}O*KY54j}Ec1X#UE5!} zDPYyWofKDyML?yKaLBe<6W5PdvpT@V$K&>Z)huku0a70pTDe?ADl37vDs)YFyblntG>u*Zl(?X0-t7u zDELNCN;0+9xImNk3bgJNg&>92j_jU?uYY>^m2@S4OKh}zrd9nr#Vki3YfZ9;9vyYH zpX*U7TVHg^&8qKFgv*?;P`3`bm;wIm8z-+-=awO`*8GWLZkbq{3sZzfI<<8A(BVsJW;s?iG|%V=M)EZ>dSTI| zd-RN93Hwq~Cs#A%#-sYFV|Io|JFqSz&ifW=3-8iA*KaL5|76d?r_GKbj&7m@4JKng ztT6;F;5~dYo=A&)!9_#+0++h*V=(TW8ve|}D8P%r6;|+R@NHDN)YNWvl9s}N7*-8M zi+qP*JfH032t#wJk`7-h<5ODaxoPa;hsw&D@q9}%zJ-aXJ)Z-9Cq4npvtYakf&1jl zU2-5*pw_8r&^iGdp!lBt)#G-A%JW>$=D5y*)A#DBgboXKqUk1Ta8c6>=Enz|lq^5D z*N&w9uX(Ct`0S656-|mGryMDhv>XRxU&L3`N8ALi14d&nFhNrP19S}DNgQqHRI`w# z7LA)_0)ZY`RNeX$f~DUgR;Z$o&;Ez_^B2cS=|dglrDch|Yx5A+y6RM|Lm|o{jy3+r zG5!8>J8Y&(?vQB(ijHUcof|*VWOeG;?3?+k`43ZhI%{)8yIv3w<3Qi0 zfpvs3`Mn(4eVjUyEpK%ra5B`%MKCmd=XOll#KdQ_oHhUVjHD&wU!Bg!@qUfS8$g)u zOxS;V@)-xr}5phGJ-tV5@rOg8CDI&zzbQ{<_K7 z?GK}s2QQVho^w*vr&J8NIk-7fmZE~c2J62p>nGWzrsY-*IQzW$@@aT&>Amzg2=-MB zK8O~IVn6UXOMxY$$^!03F_KTsUN|P0v3)Vpc&K`G^dw1)fXm^7^EBF{+{EUIyUv)u zz}z?9+FkmYacyjRd`=aqtCFjguc0uNSgD19hss>7Bbb^sEjf+nyBI5%rWBgGpx&SN za=rcKyzBT%U4ALpAPanpU-LTgB}uCEfb;`Hwei4I@2EQm*6IpF+58|-A$G>><4qq4rbo2k(|u^CtQq)vC2L*zU;^QXxGFX7(ZO`Rd;F(IoSujU@i&^ z!PiFIFV!VR34|lBnzhi1ZOZ2CU$b~q>Qfk>y|o5+f+D8oQ7u2IGHvDigO%_L-^4~# z75K;LC@~orA^#;>6)x2|(NG!_5-VK@1m>-$cV%oiZ^)-W+b7t(C zUJM%5`)%o@1ozy0${9Q)^1WV^Z zp`cOCacJB?1f z5gkdNesoOR=t8}t^y9S;*I280176gjY91Y468*LJjQANiWbybGfT_G{4C&EQ8a4QZ z9W3K^MmnCN)~<0h0xpM@fiyYuU@c}u>b#|=%oX;wScdyRRe0zT_eN&e0;T)3&Jd`V z9F%E3_#`7rcTBe^EN7=rCiCHqyV{M@3*;d~P2Ly(AS3NvP6~tSkLH{_Tyh#o<8xI+ z=P_QuwCiZ0R6$#Pw==Pq_ z!r)tT%(`q+u+RMl%q7aSOq@U;mC9*f-%eS;rJjoBni)fKU zCiGGEpKtOnxkRYwKbkxDghHTrIyYsmdd)_lR^a&r=qOMDHY^Y$CAIjgFknHjvDpY? zgMM!=Ooc`Zpm;BVJSnd^TkwEn^OJbz-Er~ZV4d+80O{dZhOv%BZ{rD6!M$J|*cB!l zpP>J6CRNxM?|@c}#H#_z#v{FN59vpg+n%@~RME|iah*s4&9C32`=!PBKmv3y>J!s4(B;~=)XH$ zEF0EKBn@ZPt%kie^zDb`u?S*KJ^l~BG6cOz_{;b)%Xa)aN{^?X{?gPHo9+CL{P=16 z>-#Zo+B`jD?vHVhVg*AAIY3u^yj!I*!eS zC171`GPvokUNwU3q=*Zu&I(Iy1WpFB-1qbso%ZO?dzG{17WWe>W?6X?hgy4vGk3jY zJ__i$4UecSs#==>@0Y7bz%$I7kh`cB$ErXhC)=3UqqJ}#mAc~WXVUu-B>nQA!P7j0 zVubqrRx$h|{*a7-%>4ueYI^Sz74|U22>zEhouW3JoV1@p;m6TZbel4--no{4-I2;eGXew7Qo7B)&-q6nQju5>=&;L26^zbhMVF8{it13S zq1&`GZt-0|1tM7~#US_EYG2ey?e;u>=wMZ);tB72FYO!+ZQm?P)IFJlm?vkhKTrFl zrgNao$E=B!(ahi&<3?e8cj9Q0P)S0xk^^rrb_jbMDbt~OM9NjwcnOoZ+>DUR?RYa3s zktZo+VWO_zXX#^?uZm;B(ZMoybM`^cnyh=H2F1lIp+yaIgzh{=slr7_@hOJZS_h-h z79vDf03=PJ@pgcZMQ}Tm42|PA6R$Ja~R~t%`oR%F8%XDxcc9x^3T9!Ptk+ zS}RS(AIylgm5xP)jRA(SmWbgl{kKnZgpW{eX?0HuOUW_#q(7ttES&rqXV4e!stg5q zF|o%vKq{OUW7k9*q{O064j<$UhUXz12SfK|fv$@4V3kqm(lvBw@xzI^;o#Cl z`}?*5txV^VDrT)~`0(dtcV{rSFJk(X6mQ3L-aQu<%OEriMa)rw<;H2DhQlAIOd zz5Jcb1u9GfmA_{I`@>|!koN86O5^SG!_n1+5^~v?wzgkeQ7~QWMOn)gzrBr&x>{=e zrBIWh4nl{OuI6BhOPJ%f<~MH6<7;+?W0ejt?amLj?uj?`Uy7~vSowtv@-eQ#xuvoz zg>JZk8=lkW%gMKJ5L3LrTn8c!-o_oy5BRO+s&Yp9!AK>=)Y4tpbBVfX26l(XCQ@?T z`a|-QqC6vE$8hh7UxL|Gb4hMCki(RC;`E-TFxtxh!b8p;6oV`v&IgHq(Oe8l&exL1 zi#WqscCFb{1ZSG8mKJ8CeL;MXZfHnOZ#;*JP`g(wFu57_aGayMx~1Y!u+N^Ych1Dv zTC&S~lY}k_Ht4I%QPZCmSL;6^_>OSZ+2$Yly<(MH?d)2{=n8D~2xqC2ybH<|`XpY6 zs9gHNrt}%+NIQ$2zF@Uar{S*iWI#;NWH0C!1k7!t4(DFah<$dTj)Tww1`e%zP6|~Ya}5AFhZjV-Bg58 zYR$2EQF1bh%h-hR@)#7`ax3w27ky5amC(3bw3$~--n&$5XRtbzza6_>@0)Gu+3;}q zwe`TzSOb`c2*JX{{XP!^k#zF0|85CGx*mgW^IFyVnQ5aizh<9^(-{rPd6!rG9(z(? zlvIdGJw5yrA0X(>BW{o|*Aa6*n5-_}`)@;rwNUmEp?~bIt1~Lb`N&dsjARxYJ?Zfm zqR{T`(xXxqn}42ohoL}*U&HUf^$=^##fR-Ob(6S$F_RzsjiEcYL>Hg{jwiJo+1JKJ z>_BbV2a_c=Iw<7fH%`&@;`GeWIa(_}cn~b}jqa94nym%^rcX7|ca+n&f-*yGf zVMLG!AgjE##QK8xu>+joF##N;G#kW61goGD4e4c#31fj)Eup8dC`{SwNal3#yr z1h*H{+~u3!*~L*y#BQ1FarbT*2q$bB$8`A#oRHC*GDx<%)KJYAp+*OW%PRHHrd|2u z`q+Q&9naqd6toUaDq}Ui8Q_T5;IA>(N#9F1O48tHLK1u(4-Ap+`^yND(wa8_3~-LA zA|QITZsE!;t$RN)KVihj)fZtMn{wOFg+zzlL79%QIEh^g1Gc5@2UlWZf1S&@5r}%4 z;8Rgi?DKOY^ZFy>pzca%CqD)$ECj$$>auw!xyG#Avyyw@m=J*_CQb#@#+_;F-5lKf zS3x6inp&0`)>i3QS9acwax7w&l6Jnux zPe$7(O2h8C!3gWjogHru9D5V>DP8CjGR9`2=F$83iU46OWcC5Ze(xw+xK&b&+YEe+ zTvKp5v#_1w;{uH?qT*EnF}YE3iXewUakB3<2J)vm;2TWyg4!*>bR~%f5n65b@O#@8 zw_=vsn)eR!)LbY{OmdaiMVhKkX7w4Ahe!Fqlf6$KJ$VwwbTlm8G?7!1gOpm}rra#z z{>Fs*C-G!hkc4dnowG+#(g}tz5CCBGq-9H*o)kF2UfK-$76bkFwIve_$?eMT>xxcG z!x)nv;Lv`V1$WUA5Gt)BfV&b5aDIB@*_#`qjCpe40(bzqciH^RT(%B#mT~9Lw24CD zo=zIsJ3!vH7O`yhb)Bb!;Z={gjCi;gce_xFihCc zzE$y#fvGkd1&CCPjARkI{<5b450c5g`Ja9!?L+2iwTh>D}i6#JE`B`0a@daM>PBEskHDAYjxhD(&-z-++ z7njSMUwb+K`oei2UC%Dm#x7s@ZL}eT>FfV)+CvMzDf5CydNi^cL#2*4=w>cETWeNV z0c5o5m{gV^Ks$j42?JM6o!)}E05}u?{o-IovPJCB_+o}?{EcecLO-#Ez)wn=OpoEM z;a-%cJGD+24uqM+1}yAK3t2O49sAIIO(p;O9~jAHs(!zl@Wy-$;_(F%&1L>|c6x{F z+@QhP+$2i2lmCZmLCjoE?N|F1drmi4BkQN*AO0Np;1|sD>u4vX5A;~4?Qqim^@sZL z$M@ImvRY^GE{5S5of`O=Fa?)xAqwK9vJGJAj!6E1qlofiGYK6n)e?sQ;}18nF=!^= z;(FbujGM*88go#PJ(psm%eTI31LKE1ZJ+m%j*|?<2@e&h=c9+@=4_m zZ&DuVxOk<^8+7)JFMEl4Ve(e~x|xCM;@Wg?AGcWz7r}tFAMsCMmMj19FZUQj+|u* zbp8yW+COQSsyLgZU+M79?QXq}xXH4b{^VP%)v3W^$C}d3g9IxCYkqXOPePPbFwkT$ zyA*)Ekktj-QwClMQgbJAvgcbc9yG0u2dz7amXXf_%Xo#ml)F zdQdGk>f=%@^myx^o&+sVA3_rLP>dB_tGt>u2DSY%ycq6uVL3eYT%2{(ySNG8mmEiL zD{G7A?fMTK&#j)%=SOBv%mxohPj+1naVt;EJYc@7I%p%+7DK5+Pq?t6;7<6-Tm~pZ zCZ7voD%c=FhE&#Bz?>8|Od4xq&4RI@J%=@}15Q-dzO&j_`I<~d5?~cVTcpYz;xI(Dv00Jujw5;b?lSX znaQdBA_@n6qb|QLWz-Mrwh}|EV5{2bVNOn#0_;3{XCofRLfio|;2OZ3MSQ93*}Vq4r#O7i09RkicgwY!U4PyquiUc&Wy$s=BiI+6-v> zAJ%Z{sM&g}nv3dBM=MTi%lS<~ zJStzaZDTD*BWh}6ecyjU_G+ZxEO&X<*6&)G19^>x2eBi^^dr zVXm@-WA=llhDS~dqLReu5~oRC#7aYt+s6Jw?ZAvag?zk>*W*BqAW@v_a$;DsBo8_- zk#sL1DzUxP`h&s#&&$(8MH$YawQd)yB?qK^Q4IdYrLibsKlFm{E{q(eDnfcu3%B_> zs~!UsXF_4Rnw{6Mzud&j`VqsEvjEwg54BIj*S2(DbKpoExoo`W<*VZ)xdgmK!xx zRP~TLzJS5E0G|P=Y$#ZjNw6w^NPFSW5j=@t3^0;uElaF7))sAmD>m=Em+1ryiz4vb zQ0m0HjYn?M;~;z+s|`U^ou!9ma*1+KB3{MY=rLDL9?{mUttOZl{qSM-(mZFzCr$H! z8^Z)0KH$(y3atp~buu|+aQXWCobW>`D&8Ighp9QC6uO=unAv=PcKK*8v>z{4PL;|Y z;vbR9T?!Q)l)jE8iVuz%Clh7GiX2!X@dvB(b=$>OwNSc1t;H)2mYmbmuIjnQc#l=V zrB69uxi~+p?ud-G70r2>(L*lM>B{?EH_v&j-oEmoq}j-ux>%jFKp8K%eCX&O0kN5S zJw2Ptn312RAK~;y#-aR5+v)@YE0tp}-i;J(#~uQD%AtCaX7NUm!*PBuh<|r`r}SF# z^j`Vw!)d(WU zbf;3s>HQnx5z3X1OHowz5hU#y<8X7{iK-*&+an~6AvY`E$?Ct3K;A4Gm=E&`_3WDO zYEgs^u+teK#*mIPo7XEkD&9DR)5rB~$AEC&IxDikT$z{~uosM+8CkH}Q$FhphL9)l z8Xn{pZ?T%>79V}*G9Tg;I!W3ON}Xz}h$ksa2=m8A^|8c=B{N_*hSR;P?t$g;S% zImEc|CK(t0%0qvDpZA}e539?>Ma06|XliCzS+typ`-LUgQ!Xi45FX(uzUPU#8Q<}?@#Fm-xS3bw(H-Fu5dZvTa)>0U^&D;`h)1CbaN93 z;}-=>ydaUjbO5IV3ayPh4;1Ct;5+rXLyb_ojg zT%KBM^X@(>Tpn{@{)h*^5=em;`#`id{IJNl4m?2c)ThHLX~ZSM%Qf<+U_oQqe? z=&0HFFu{3u#D@_@UlkX|kl?_eb4=zVzdCw@gKl2Vke`zi1%qA~6WM`>Isr$aq5XOQ z86-T;SL0o%g3RVQjj$ai_|e?60?n*U<3y=^2;G<`11!H{B{{Rr>WxE2d#U_~A?nH} z77abpye{RbAD__~EIpCA)zHh?Cd|ui>>VG?h&^5EzTInkdZBu?RpXnCnB(Qe{fJNt zV)|eBDIm14(L?~!cNLg$8FJ-o3t9ZtRt77BBM_{LjT!f|>46{C&>go*vFH0t^6(3u zFCa_z97P^l<)Sz0^>i@(>U)wb@j&t&dgb}HE=4={XP;a=KPG(;FFPgD$nA2m=|jaC4NNwbL3~Tg$YO9xq^E2 zQD{>p8Ey6<;42&eVT158;!_Zwug6i0w=u@dpM!D*h&G0zl|d=?j6hm8Op4&LVO>Q& zv^3LV)yTTY7vAI0os~@kyn?!P!|;}%(64`_5xUKHxwsf)8M$T|6rrDqXkRUno##q7 zzjJXv=jaw27>Z!i9xPBd{-5d+z*-3lrJ|o{JP*;2;GiO~+QsiRPj<2uZGczJ6r$~A zA>my;T1jk{%8e|=Ukcc)Q9Nj6KUoh9pnZ1^{hr$txoO|s_aj4E=MRV+y&uuiz7@{Z zQ@&Le4uS3LPfY0H zk7q#i&jpuvBV?fYw)W=$lt9T1lXb}C#oM}<9KGc7q|_nzBooPH9+`X)&ext(gmmx( z;LBSp{Hr&*f^`)XKVlK%rMsaSZZ^T{Lh1h??ajlX-v9q$omNRITM=_gNJ0xK+niG& z9Hz(~b2^e`8k3j|#>~lDmV6?dh$(Bh#*&zC5ocMO7IxTzrocUbYnfIB~_B{ybs5y8w4Ds#|ReS<(1U?cgYoDq| zKKLD?5?|OyaGjBtg*}yJAwFnXns9TsdcJ4!Dg}yuv2cFMzLklgV1T7?hwGG0!PkCN zY3ya+2jfk+3!vsm zvZ%chj7}v*Mz0cKg!fa8VYC^AyRZI)-!~g@a)olU7JYI$iU-51*`3$RCPMO`W|@id z&?R#pybxPr+~ePX=JM&{bhi$lzW2(Ef>sJh2ae!D5pv6-^hK+Z*qGS9ovw#>gUAA= zBQ(z~RG49y&*a4& zEAY<9pe>wYb19V>8mUG5Tpvdd7dRS^MNx98!y64GDV0o|E~Q(7`SyVFdKv1+fjSZq z*nZlKO126Td<2d{fEPT&?EVqi&%_b_Se*x~o*Dk`LdMprg*c4@}_G$wYx8EyK=t zf}C<2qPFL9OoO#J5m;{B)@o+0^X6D{roN1Z2(Z8Yu@>?5=t|^(`^q6%q=v;XJscAjhC~V;qL&TSP!c`cU9$^GH zsEUl~oV!itr@Wzki`~9fp4d~L&OF+F-!5b3(eykv5b*1Rk`1>B9}Bxhu_@T(2-U`K z#kH=JPbuWJYjD&edjr5~A8aU#17!Umc5#EV6-3T3MPe`_lOb?0`APO(JyXD2?~t8& zMTfGdwYGPB?Y%Ng7n3|UC;CT z18jtTH!Tg`kX!^;E-x0HZN4;#T6!827yX@h>@$PlPL(-hPK%;=zaa$(&=(Fr9O z!FK6LTXY4XnF;)=GgYKLx`O`{be}vQnM1i=-1?V|N$MzNt3@+2xmK&$BGmDxF^>Ij zZJCrza}x@c*2b@!w3LuPNa(=PmnD&&@8CL z5I>mhu!`UnOu+W~1yf`2QAj1D+SV)4W&J#o{NmnVkwqCf(W`D(%|!1x7Pz*QJ&;=Z0P(%9JxH@9ZBGDpMEq1F1Thg(Rl%4%m5zuc_@qV zQ)`epP#BV!F?T0TTl@Ajk@mrZx<&$q8i@^TE4U!z)6{~ER=#iljS*c2Wn>xippDiN zrTuq0+&NeSZOKEIchf`aKMt zp)q+azo>tK5|_~&*+y=gnX0Y9-xL2HPn-t#&3NRWm)xPB9X3A$J0ztmLI1;zd)c4v zjieHT`zpj4aB4qUpcYA@BmUze|u>ysgurPI~+#z204y!5cH4?>GiNbfuFKgR5#~P1M^T`0LLekb54NCkf^tA zR_rO5X*2uzqN|=N8uQ(1CFCe~_5#0(K479ZK}Tn|pfXe88aMw{TGBZ8tmuG^PUD@< z2(;sb!&CNNGOl@pvq^4TNqENV*>h`aYEZ-}^*YDC$E)4wnoE$W?YT3o-thaDm$ zhdy?<_w*0a_N>cgR=kCId#LC`H10KeaBP3IgU zBv{yXciB(4PEiD;1X4#kX$$BeF~(1e5`li7mL=y`T3M@VymaY{ZDLXizuW-a z!`S7Z)Q88ORx-Oi@04As?o!xP4IFCy3Q;6gBf?mg0og=dlpwk#eTla| zeIIZuXI7Hx%&gBKau@nEr#9IJgnsWL1b0zmj4OXy-h9g2rS0;_S7KM`##y-3P`1n53Xr4&`|bwFU{4uZ}DYUkpJXUt3`(ENxuN zF0RMPMmE$+1NI$TzGPlEjl;RidQ;;x^2L>4SL$o9SOQd4&KVgtQu5?E*qh+Oc+3Jt zTE-GZ0`}?{8H%%0k}}o*3oKJ^6(wF)klY66vHsuV#PL5OOh;~E{6XII(XWmCrWm z$+)}TwnA`T4lVk<_}L3?v`X|;z%AFg&UZEOoO}SZVU__H1t35ZHZ|?tkI-C49s((jMe;J#0ccqs68J*K% zsPsPT>(eh$=v$4B(%ibq33z!vkcjvJp2YYhLOZc3HwWy63xNJp3KKY!VUkTy9;kQO z35*N5WDS61QL}P-=DjG|GmhJb*!+nz&n8sX1?LV!$SxZt#;}Z?h0A->vYb&pSzb~R z+LH9J`2+{pa3)apgd@#EN#N zF&tIn6H`$~IxHIk=F`ag8;CB(_!Ky$@e*SD5&TJRrhEwf#E3eV+&h@eIn1hyTuI^R zye_cK^B9#_sy&!t9GGvBoI#h*vFWs8FTAI7sFt~N+O^@vxUhu|PS4_{%bCYH3i~Fg zZQC)?s2j^UH2watJUjQ3`&`TGp^I60G*=_Gi4!Hn!8#jNB=U49Dg?XH`tK~+(3HT= z;E%|xb2eur*R#&){62pe{t!GJdiM6N?vEZPd$?ZsX~z)_@2K`vfWLwtE4xYT0t@+& zxZ$oWa+4`|3ui=5(jvxn#$NCubVFz1!HAR%>O+YRm%L4~4;^qtAc5_*F>unZuY&@9 zYXfv_xuM2MeU}er|HvsXSQJh+l_?gMryOa@x2vvEH13$mmfx9OlVkAB!Io-?%(b+( z;LJx(MKowyT%9xb(H=H-IOLgd5cUs*~e?)&C_Ucq) zeacgyqh>zjiuyXMN%*a1oP6CGi*@^P)a4(!d~0*r&T5b_tV1Q@0Q^}n{&0!EG+%a7 zatvs*z{SQ8s>9~kzgS-$koOCT3F>NIb0Q|ue;)q)!R@N=Vi0Q;xevFy{W=qCtugb9 z@Hh2W^DT8H<{ zI-Aht6KSI@wCy2tGatazYfOz?{cieNqKzmDq)pzTU=$dx_wp)*rC6HpT9Wd3C8_JZ z>a8DFb7`TJ^e~#lZ>>Hj6#A><50EV~pGjM=FBi=qjB2YqApJAA<++yP!v6 zJs|mLCVkRKtKB@kn<^;jPy)|{=Uc2Q$buxA0cD-#Ap|8x{CC%}n@w~<>Nq@^Y~<-V zibjV;HlvrYnu|yI%Yok)Dtk&t?V~Ggf+nZpa>YwjYl~Bfm2Nq@p_JKaW0 zc=vvg#m(ntX%0#g$HR>3$g3Hy<9hMYrnN5XOL=PR@f_TbdR#DX&M^&NOF8Pu`ttbh z-GzKKT#sLyS;Tt?d)_r}jjyY%J?mIU#g|6kZa1@JF!3BAaVJD+phh4GXJv;MNXHz1(GF_Xg zpLEc7zxIs1{n*z}{G#BS`O^WtLnDr*^F8@7eMWuG#Jk3Zp3<*b-^XPJ34#QxqEn{A zkMFkb+I6$7Tt~^ZHgwdWg8Z`Nn9A_e5^B?9o$X{sm^aalzFScKU>d#y@_oZO&?w%X zEIGg(Q0gdx)qg@R`RJ!a_WS8LG;)415ydK4;-dB_+p(>!7aY~R#8`~b5{ zW@X-j>{10BgIdYCx&@76xO{|?-~0(b?|D&6(|=m@$Cpj9uj9uIV;K#T7o5kRM!p=W zy3YH7K4&Xt#ZHd1MUpc%95DCS@GkI!|5bI~Lk!ep$OpqgEeAH9*-6?155%OwcQ^7+ zyL|YaY2}S6#ijiE!79Keue^6_Ri>tezu)3U)nPsIOx)?7y!ysR`)6~kS3Zp;Hos`O zd!^8HzRwbMGyBI{oZsNTdC?Ww6zP>`I|9-->HJq}@BrNmGUP^e!^dT?`!+kEOhHOd zOdCBz7|QI*59)%cFPsR`Q0nyUN$DXRA6auUoH+85*=kn2kcX*$8~)4+RsGSQ{fp_c zi#Fx#Q0n86K!r+Mn&W(%N)%C-UO-YK46;})6_Pywg|1k+VByY5dJzg&BL+JyO7}?} zk-_U!f}TLJdn_j=(ZH$ACR%%#>saai{Pr(8Dl*omAjR7`g|*RFnN4h1D_zSS3F$T^ zSIJ!wZ<eg~ikeSWT-oYJ2~XXQ5iDaVB5?)G9Fog%S3 zc!H;7m!w)+@{io-aj-a(Nbxx$r0*%KChZ)W8u|+{-A;T6^b9hqC;-QKaPM^dFS`F~ zHUv7z<-i3)9OG-57bs8eoNL#4ZYmpm$M}(sTmzLL%pZXH_bnF#>3FY*$P-tIU$q2N z5b1r^coK3w-CPP9;KNrw$H01~!1@RfFz6VWUriLdE;LBYA$M{39DH+YoWOntlZrOh z75Itj0Z#igo%PFjcioevrel!ZAXB&p-k@0)Vf!Rv#w1C$Re<2zb2X7^ zx%t*>d5NvzGis2QP{Cd3kuoj)L&h0zb*jMW^?mQWvY?Uk)VaL7dT~8BH~UkxYhSOO zzN^{EtJlm@Gi(Qj=pJl8e#HQ3cv7eFzp64Ptu6os_)ef;zX6vO9Y6ZtwgkS!O2jkS z`Fq*_WpfnKvLXTHkdM9~mtxlD{1l64ef>WxH{1V(3b?|4*c17S;1DCluEd3h!co)( zXqC9ghf9t2^Wc-`Zd#>LDp6*9$DZ~`ua2OJJc873d~-65LzH^QI~v1{eN5RU__ zgpc?u;b4hUIR{>+b>^F=v?_r9*4ql`bT2_`=pVTc%h))(8_no*j z;Fp|F^LH8hCFa0*-mePjTsdg)0N}klI$EPrdR10^4S?j%)%7ni$;#5~18$0zJ{5wm z!?Z=kScl+I{`;&?ET-%jueb-?N;X~jhGFXcQ&b67?TVD zM!pVBF^ce~4fmv>fFM)V)cjx5g0;BTprej^6VT1JJ&{1OSkqyz`Va5Dl?O=V+!* z=5_IFVe)(Hs0tmPSU-4>VT5ndU^a-7)z6GIHMMQ{Y-p$Ua7R_$*d3Aw-y)0&D7+Oz zb)}3SMs2G2>?zUEj0>-n=t-L?hOf#OFGJ0OR~w&;mo9`yamfb|C$Ann{N%_VRW@^P z_UPmi3Vqe+hcNqjmJc<$(wT_eqN1e)^ux7`qcP$IU66VdQ{ zaDlrbvI}Hj1TD#J;R>MG!sKiW;2EEx2(IQL3FKyb>*zm2u86(3v5oQ7#1Ctj-HSzs zK!5kX$!x+UW@{|hcXHdtw=rS47uG$rRo8$!oShgT-}7m3GSl!CXTFrrFl^4NFRmYb zo*H)YX_-aD*Dr{oYkl9An4v2!H-?s`nr4?sfMP6?^;xhwmE`azUP4@;j&>a?;k~vx zU5+;dk{Tg{iqMSLP(C01J5%%8h-s`=Xdlx@xQ$#Dyy2N_bzGG)5MH-THkx)q?PKkA zEI(8Hxa_UtNzbp9&fPYmZ;t%7N7(tm)u#d4G2gRaWmr@>$FMh=hMl6w0rOLk5xlca ziCe)3Sowt1CbJQGpQ!DnrFDEsMNtwX9N)yy+bU@n{*zSP0)N5 zb}X%6k;lwNzB+_S8kPA6xJSO&YZ||D%^7a0I~^OjYTDCnNB>FQ+qT2NJWgf4+MLCz zls;oUj@9pF2reTNYz(B&L3eqO-9Mdq?{WVO<^fTTt_S(HkHupe>dJW4QwpI#-|Vn= z|FO<(_0_#WWuF{B_a0QwGEJR3;L>>GxzE!tjX`QsW!Cb^u3txuyfFcO} zdBp(ZWZLIg%-ffv(Ew*!VjQ zjuVD+qxrFxMFhVGWg0d;r86#(UySrdj0@UU3=JzH#}+1Fr7$_hG=;EPT0@*Jv6x-5 z1gHkB*HFKJ+McgQu7egutpZTF3C`@C)Mi}}%(u3+4&lv%rsG`Ud*|}BO<&F#?Srxx}R2qAq$ts;$3EiMoTlzbDPXyIXnhNWyA4D2l zC_3rf_bLw*28}(j1Hl#V>L$kk)WZrUHwa$t={g3L#HRt-zIFsLZ14fGVL4lX;+d@{ z6XXf+TB3SLyYcD*J|``Z$IuS8`57n-1kTuwv|1tGXkZepPH#^$lEBN&)2$p{pj^RQ zG}d+3^({PdCAq|wJJ%By-nwx1oF&jxM8RX0SwlX(g@`2mx5Lw zikw7zRUtV@1AZx0!lDvXtwdvpa6n>=#&i?3-GydJa^JAd#OIxNZWFJ#fV#=VOr+4$u-}DWLi`7PzWBowwlS>y1|H;wGyXO zN#2(2cIGJL-N;YTIaCM7jj$$o3}d>CB=CfNgmGt=bc8dm0utXu0G}~W10U58PW@@4 zj<HyA>XN}eJ5OkWQZ(K@W~ zmZw<=ztlR@$*p#5G;z6oCF^n7(buKL%)4PMOd!Uu?!CmtI5GHYXpP<%dApP8C3>H- z9p}w&v{2a--akXVcFUM1p`x;st@xZG9@ukidBZChesCj1Xc% zo{b`;FPQ0(>C_LmMvucUMClGqz0M z9=fvdOkv#|IOv4~A6ZLF#~Ua9Mu!>ggF^lam>Vg)G+LqVx-SvjdX%Oiq+NappD|cs z+~t;JaJl*@^Qpdm2t~6Ztd8?7${B-#BSv6JB!Mp?h1dx2(^)LhPH7H(pE)?eKh4J& z$tXev(Mv%^S9O4Z)!~s3OQ~DShyj__aOBjMMG?nPuvT8LpMqB?hjLB!hiKevoAD!9 z!<~behZ{%NT%xb*x}-E!8atQ=4~MT8PUccQ?zZMPgcxCmB6~G8{vus>)E+kQcMmYZ zdiynIMR_)2-jVeKhZye$AswQmf+14?_<#VV?iFcp|FOAlV)OO5L!jUL9uE`C%*T)$ zw}nVZe}yj(4!sYU)Oc`NR<9EqQ@V+A_+7(RXsnRX-|2rCs^-;dzM=0Q!D^DzIXi@b z$>4UC*T27F%GUs$cQ?VO%$kr~R@6&tX<1u))Au9kb}WD8%J|OMvwi40leXvJNwv8x z*02C8>r1ZhPWlgr$LCo;%}*sr{OVRmLo+`NLT4AJw-ty%<)PgQa4`b#yI7G^%D8Hg zhY)yD!SUySZG^My;5F))Y&SF>dCBTZ9nP}L!isgqoP9Ao^C!G(6KhpGUPH1K{6=lM zPIyKC2^#q#6PoQvF}{Z0=4Z!1{137W-ejnF!6vuDi6{K^Bi96?SU)6eDrvJvrq z$*f;N2Z`9wv-L|aMB`R?U;|JMM%hVW-`{HxgkqYNv3i5`=y34a%~Ma$E!UW zEo64Z6mrsHT+agWNXgCy+I`!Df)q{-p(3eri*#dDS9K~IBRzx~e>YnKCkGgepgui! zJcX)gqyQJTCjO+Gy{OmUf&ahnAcr>;s}b962)hU!DKqwxW5|5~{dr6hDa-&=ZGX}} zZ01gsK|mE)-CIi(!3JQL5ca6Gpfc_(Ic=+ul5e*gy`lNN`Y}Lz;##6{O;U#_ocwMo z=HHXcW6cCzzCu!jWp#;INtoWo1W};OtLU`Omm|DK0@(?8s97kML!Fq6)9*l zfYixFsXjj8vzR|Bs*YAoKY_~UG=#3JG1URr^t6{_h{XMz2{CA389!Rbs$RRbv6-tR z*@qEDLPp~KK-(o5Z#09*@B}A@V2R7VCbS1EFEW(*hKk%9$-jUc!tZ_Ve}OyT>jH(B z;X;SsTOu|EfAh7kgzP<^7>8l?b9uq#l;n4Gs_|Kz-Q!AqWACO3bVO*@(6@;S5Z)%h zULiY4_eigb9*JR)laH{eM8LEY=%>-O*^5PoM;Z+o2j3P$!^Az;Li0Q|ik@)Wbbdj* zPD=Z<19Nkim#Zn0#P+L4(2%o z6KmgenutC;^1hFX4mOv4g(1UTAg3D7wry)BXr1Zn zz1*CK7&^Y@-ZV08{7zQkGWK}E!Dq=d0{!Utz)yG;VbBtw zFh_}6|5fM3Ib9MMmrSG0B8`GT`2MgrDk2s=L*9q7I1in2-Z#;~PMzTRLH+F(N5@)? zEWH+UHv(&u9#&M(_pHRKyPhb!@TkN6kSZ#8l1vL7Ygot`oBggVESiz+Xb%Ezdn+AN zFEf*6miU{}T7q?mh59|2Do&}Ja}bo`?qlJJd4RDHl)QqKTG|0I4=2TKeuP>3h7nUI z-@#q}l8Y=%Se;8jKuveqf=|-SFvBe#>G3%<>uHst0ia=hZ`Z(unW86klB>|9kS*(& z{Vjpl+ly57#?iV6uvd(FXOk;woqIn9w-^-_hQA02j-+MyZ&>?w$(IhsmatK3Y@3p} z>$lDCgj}y2&a=4l7&N@X_>oLorb`{$zgJT@E8EcvXo-Q4m`7&AJBVtazCj%CeRTsOx{UsBI|)Snxr#=r{dK~%8@Jka1-1}nEaa3b`(b! zNM`=z9b66X6!S0m)n~Noqh~BL)lqClXB+$)3tJe`lm9N}VSODgSGe?uT*GqFY`!X3 zop*kJkQM%=A*4E_jzyzPpclp^bKsgk#F#E5ZYG8?l3)}wR+n`U&%BcX!)+Jc2dYws zfLI`ilb;Dl4xQMLy zr~Vi)h{ju2dU?;m1ldkpr~98HC-rz-Wk!IY{#Tmqh z)&oJ@!EKOxBHj>pwE-^6}AUDo=?aN4Q|lj+Xx{p3TE zD5r>SW{Zvq)t6McMlhf!K-i8e?iglywFvC0D=IQg03g|^1XuUHD~g~ibjjeQ#W{7w z&?}#h+gFBK^gMd;f_Z*ECax_hqv(m^y|^&cl7U#?R)4=WpFYpwTl=+a+%+XLrb+OI zq_73CqD?%+e4HdRCV&ambyV-z3S2!-=;*e?FDW!cO7LAuV zzLP!>LD2$xe;hd@uv{F2GF4GIu$xJu=TIul80Vv zMpsP#uKArg{#Cgkd*|)W^O$@WL(g~2SAMElQ`88-qR0sf5X=He1dv=+3VZp3f|NJf zN9v_HguQ+cvNr;vb!{lVPpN>u&j9nlz0c-sG-ZPgPqa0)0a0TB* zi`AH$B|I8RKh_X?&Y;Ik=u+b*3U8o!v<^GqSIB+KEI7F@d-#7?;rxHWg#N#eSP%I0 zN@74;x!{`6<`QEg3a3gO6_BnX7N$1qJU9h!(p1!lMc8l{!E_E#gD-#1;HM7DE|w!9ps_)Z{{aA{WgaU*Eg@rop`TTbauBh#NvgqYmpT*+*MrJ&AMTaW)3oCe*;S;;{o@hM12b|72y z2N+YfWNWqv&3xAUp;fg8Hw7ff2!|l^4rWTmQl#A|D08_A_2Y*PLw>W+e#9j{XerE0 z(LOtvg0ZrAb4`(>v-OJD@vmsHGaE698JtQbpnLtP=Sq^^8Q71zb}>b<`noH&(f&_A z;j?lJj}z*^o1zDw&MMjtzI+o0q~18SGkp6QB41bdN;KgHbqn*nD6bpEcYOW)Lp@{% z1OsK#<;toHrN-4Srb0KqHdHTo#;l}M=99_Qlp3}CGZ`h{dEq8|c#p3dbWW#ArkqwC zf^*ZV-tPfmJQ|z)~ch zTxb2O^be+s1uLh-m&an%jFWtBCm(xU&Mkf%v&!gJD{%1BV^XB&%Hq3Rt1bR=97+te z>^nUl73-TD>TqU>?QCQ=N{73E0m%_QQ5j9^OVQ#;psxB-rY-xxP;XTg_P!yi5kt|) zo^|b`f<~uOyoHdJxJFXMIZf-Oa6w9=@h~qoD3Dud=-ue+dq}d$$juoLm+xU!#4-INrBAcmcm&O}ccB`GVre z8m}k`F=aN4YMp&|M7X=q(d}}j1IO62VbpXvJEXh1R{N`Breq%rMEnilO8Q4G4c4$- zqPAIdABqwd@ccl1df;>~3H+|dJwy%$aJ?L*Fhr=*Kll5)k@q=T}vA*l9+E1%X z_Re%LUIB#ZcTu4`VpdboepK+@?gmf1*G`36k0s{m%RG^XPvtu z;$I>nw2z!jt=3p8bKMCY=jp8xJd!K&)H*UbhF93x6~%cQMr`+{vmq5ZUy zL`6X+zgM`(!|)ThE5POx2qcNJhu}8{*8(|VW)xuYum zT*LKW9*#_FvquO9GE>NA{R8LwZBsixq|<91L+^OZz7Y989d4sGzuMjSSK(b?l|MNreE=ihWA zFe4X zty8oJl)lxFp;XS{NE*F`1?v`=b=Orn(s!Q{J)UzOVVrU!@bY2}Xp6N?{NEqKw2oG} zhpUVl-g(PJwmvor^L=f{^6}>{PnjdZ-iZfzk#;>IiVW%L^G$@Zw*+foIGnPiDLg#Y z9Yan4O6K1d-6U?vgBAB%t(7{7%FruCB)6>gVL?oX?puELS8nNx@>2`pMl}%&BTISMLC{V@tn!a_tUr%;|{q zTTlJ-VriA_~TN&!G+QJo~LE84ydpP6)vIkmVQ1mUzj(s-3~sT4ocr$ zNkpu725paiu8>t>H#zvOcAcUv|jA0A0-JOAfZJHCR-w zcF2Bani5lFyNa|T+JXMTJ%T#&V`!d@MONQTJ8au=6HuxpqXdxIz8M$Due1|e3dLZB zz}@45!3Q0Itg-%es8LVhft~{Aw{r{ULi$_jDr8X+`67j``f`7j(6!oMxr#*73UE0| zRPR*yZr;^VUCflIU}W;!ldC`+ z+G3rVyj(uKrW~S|P4@Z~&70a8407ZotLxXdu*u2#sUi$yk3Ct12voP;#1};hTw_ zXJq43)QY8s64^k^z-%&~pob8k-mH6a;80p=u*LfVa%V&on7VB?8ePUb2J`qbqoEe> z&W+o*c!iq2pyB^KU|$WphrT;o^!UXHR`o|T=Me@moA-IL<*z}-%vxBGPn)j8M8Tuj zVTY+7I_rLht3j*b;xm#>0;Q#TfhN~}i7%iV*}*qSeiry=PLq|KY9?)CYeUsGZoub# z-czHtwiQx(D0K^`{81LIO~4@!QHh+?G}JUi=#6P>Wal{a-QhS>(QWEk#tiW>I6??3$i%-yzyHI#&CA09SCDnSX3Ozh-#KPILTjk!2> z3yrnb@ftR>^u9$gGIVER{wNx}%)~03``SparzN9&Y2Ibj*Qu9EBY!r{Zy2@Kh&2s_ z%-j7HAuKlo)(%%{)#Z|Y!kz9M8wh%avu|(Nox{!C6?_+CN;N{2%xUPBJypm zssGB?I}Ne{VnZ#fD+ziVAyA(l=bWN zqi4`%@kL*`hwcZqs2@4k+^jPo`Be3fTwGnKk7OI9890qp#+x)iCk4e!E-3@6=;k5J z>!cx5{P$1=CTUo|JGd}PEuxFFFU{V0v;T-$S~V)R(Dl1Jb9osn&*$bZJCr^+@XP0< zr_lj@E7-o8mA28Em9g1ySdx{IQd0JtAsp(LwDv2(3fxN)n07{meo~3xRY<2jLQy|u z>|=<*Grg>Bxh<#IisvGyk0-rs(stkcic(XH@?ra;e5sGxk%U12r(OdkS>hIoNj!1K z8Z1HMHpLIl)mrZ)Zkv>xsQ1;nxTto1@Qt~KX^~2kT1>q~*^3m1UokJTW7Ybz0-s&` z&zCP>GLMO^s`Kb$O|#KFvOMJ3OE@@&*P0fi^pi-x=*Cl3gF9b4vvnl40ijQ!_V6t^FQoZaPq z!MPv0w>>ecxl;V+wR(JYt_}Zbq(8su3qLIP<5)JA+*wKZxm_5FlmjN?slciX(59d# z`bm-cPy%K;ccgsGxBUZdphoFFPXHP_$_o{pLkmu&g^tnWj0$#Xv={7nbaPE}Z5YZJ zb(b#srU+1Aon#dpwViGwH2D*+$^#m5=PV}h*1|d(*H6Jih`FcP)f67W(E(1{TGFJR zdTs=HUeFm(Te$CA*FsacEh=udUE|rN9;5Q%F!P2GKV+=+=*CA0Bz@T$F1`Wj^AhEs z%X&zP0F}x3C`JmBa_Y#_ey}TouTO-T9op8E7FyOna-O4+mM?w6eT_k+~rEr zI=ZQBfB=)G(su$T;%>SQWIl~)M?y}mCcLSGIGR6HTe3jcX0LwGb_GqXLwd(SV5TM04+GDB?=xsul4J{ z9NJ9}c(5PaU>pC)0sQEy@cMsKT3sikj&a-n5BA;zs>!Tf8^*3Ef>Z?|c0fuT1yMjU zHV_aHP!JF@iU=V>25A98q9ULmFoM7cLR3nmMoNgZM7oGb2}Np1P^pmwAv}`ezn%Hc zd){-__xBC#go1Ee`p_U7VYE+J0OXif@B zKO^qxoC_F1TZy~70=0(V9I4&5j73X?5l1{g zhr*FJvX1wkjqlB`N-T49@Sa)-HV)(4i+(|PBHt&l?l9K^!v>&qUr1BAgw1l`Jswp7 zd<$xei5`>fdZYhrX|Fzc?Th=wu2ZP7@Bk%{X4sY0D?faOG71VRyK-RMIj>`z>ls7r+ zkEXKelHN)V(-lhwqbhyn1=V*IE~k0MT{y)kuuJ+xGEnLpLY)6hY(F^NmE&woxxB47 zbtF{(8qEp@!*?LLrvTt)-E8eR=MWpfUI)NZr`NZD^R?Z!aiS1ApAffZ zJ?=$sJNwAJZ!2!x$f)TCF0x%YghLBu&3H*Jp%EjAjd(?rG1dW<5EZOeQ>bg-JvL?o zmVD+#zwjtqY8U^I!sw$yufc33XMC2&&(YT_`W@yQhh-}z;sb`AAG%n1rv;(D>IJ;a zQ{T2%gK{mc3SDO7KflBx3T5cx4OZL)b`X&lT!$!K7s29X#ud1rt6;)CcsLM+0NZ0# z)8kzB&^ZQ9Y8a96#-^9vG~-r~kq>b8lc_(Em>1%lJ23oqL8D5@h zu)jPYru6GxLdF1Pzx?wrVH)#aXehLLF!_st&uGl+uV{9Ma0_6`qIlKpcnXimhRr@; zh0*T;(}_(q?f$^IjnEhNQbTOGOXHG3gl%pAoY08NWGmef{@_>O?R+=f@&YZ%)Ihm7 z>sYV&888J;wYSRl!`?l8LLa%`!TkA~Hp)ju&XDUS((U?p);F>%)2qGhZzDs8z22;m^Bk;OYRl6_IZiN@_BV}U?8m=w95!`^#EozEA0dQsP z4XrP0DtmTx=?k{P+bJbA@&1_2Z>Re5PE)OY4Mu;Tr^>xgEvhUE+u=CE@Br`^AqI;`qsTDbmuWmwKl5 z>L&Wyp&5^=gR06(IP`MqSrvf>I7iCU*5kaPIc|Yij(m?;7FFv5tlHE-iTKV0+bjzB z!}n_oPd~+$4hjS+b)yHkOVPs9AEAf_L-3G+8pj-T3Wg6aZT0PQGzen6)jChwRxexb zt!3q`JKgTfK%4Ttsvc@yc&Ki-y*qbqUHe|o0KS!azDsU+n3KvH3A_iMLFbymp?&?F zi17k?3``X;w*V>|&D=scY8Q@arpfcv6HKpz8(pw@LeIzG3FiRwPe3FqczK$43?ws)>!(Z_z5rC*uY*OUf|42 zh;gxYseZmdht33Y&Y*rC9zIEm^~!yqVwmiGAvn)qUj?nLOKb1E>BHyUS!&Mb&e??d zimuM7`=Nwwx+j7rjueaS`I~hxF$kc?Qx&8LMvnd7g zXhf_%ixex|>&cG&s`KRb8&`K%3cWAxp^S4&p4ldue3XrX+rtp>DHp6v9Tq-WkH(%f zd}*wY^6$xhoXI(Qn(pR6o?iT-Uqb+8gS+66gTYw=_A^ix4&Vg?uTo9CG)}v3u|pOs zT|cVUYwRXB+LTN#B4#f7D{QI5qBA=n=`EP z}2_`dYQ{;G$Ibub+4m z^@ylMLR~ju=?Dx+0%T>P_DS1dQn=qol(d}=`g9CScE<&T&d4!@-k)6S?ZZ}yneC)3AvQ=HN zklo90O&e_axYR(0cB%_y34mrB3y+~~5hVzB(X_iMVaLMEVjF=q4r!bqIb~QIH%6z{ zmT(bq#(`u=|Ey!|Chm~U(+&@>pCYw=imo`APNp1^)0nR+Zg(0uZ4~;P1U)W!#oDbK zc-qyd;LQzlAp2zJCzQ?>?gsORC5ow8Be*a_tYAi%tVNk9i%2+2^?RQEw7n=3Ehqw| zRuDX{qN#0c|J)6$YU~1Y(SBT{+&AjA^SkL&#ILy9!fVy-^mC`#0o&j|Z;QnSH|GMY5=O-E%74>L?nm%iF98u%KM7t zq@6DB>?W#*HTB#MS+g}#CZaQ}K^24hi@-$8yu95Zo z7<1!BwK=95Ps#yTLq)z27YTObU!|CQr!z+D)))aOS1wNy=fu;ADstC}s?EZ#eb==> zxHGEK!K!7WAfqPaEK@4ZJFLVND@hKC`~#zRbjMCIPe zW!NJ+cd}!-wO^r_W=9UZo*g$ZDVJk(Fo=wn9Px2`kXI!^|bpY@k=~8Tih3Fosq``yhx6SSpVGj zGo4dYYD?I=wBfQ{uR|l;BKDia1H%L;z*BT}Ml1;s3irSSWcS5_@g_KYlORDvAvpgH zMhguOiAw{)Q8W}Z61xGk5Pe#hIt=^&??WC91`D?^&U7nY1tXZv~1;I6&(K*l0Hl&NUbVw6^8k#{2j$WfH4v{(A^xAh)Px7_T#Gx4c z;H7D6zIYEPXANp0^A?NN-ukU5^X~mOiPxSW6ClrEM0%)z4Zb46seh@t{4apeANcmB z4>8^i6G%=Xm%|v7zw?|?;Dj?G>HK2u$QTa zy9a*V)$iOh{h{Ja|}L?fiL!Od8g`fJbXBmC~7&47-0bu6}8$ z4aDfGch%A{`U#+959nT%)C1U9J1*^Bc=4<2%{rS5YkTik-MQAY$>rfoSE(ifIUo$AzfyjSm&%ikB* z_nRSe>6=6z;i=g4=E3jKf*p0=6+l|Vnea*3p-Px_OM?W+Hbft~?- ztwu_GNljr@<}YpX9;;qEo-f;_cd*7U`o`hB#50|;235rue}fBy{CiM|u&}b1FvkaH z&$gJAb7exrTSU3;H;KtLpdZWRfP^zueht$TBK%750(n;FMt~Hc52}BY(AC&T>i}h* z1LDqV;G?Wq@J#|h+{Ks9DTNbR;>)6^!QUi))NvF8)e)lb|dM0pJ=;%l%8{Demd=K;&Gia%EGqW{;Mp0?JjRpi7W4y z$#}KSH3{+N)#3i({FO5^%ezVcnxOr$a=|~K-aessanZD7-{5?`hLyOe^ytD+>^(>E zzW%3FE46~_38}+vcjdf)A^F+OwmN>Mh8r^<6?~W>EXZ`zxi%nwX&XG*UnL-ZjZOk* z;m(s5puTww)HC5;QeouEZxX+T7&1kx^~gfGk#7?7{F{G0_OEgHYd-w7F8+!Sf5pka z_KUyv&HwhC;E{7r=(G0`{vnsOcL5D~=5}SDrW%l{$f0*sUrV}Bd8&bP?X7g>aoh42 zfmeb*Q(cYwA9W4=u6z67)WY`~+4j$%dZUZrD|XQrW;}ie4L|#5GqgWe&HF?3)9suD zVN@V}SzG~hdreb+OquInFgyLbL(ji&a7e$lS&0qfr-;aSxcI$tBcg)PGm8s`a{mIDHlJ5qUWkJ+>@ycHMSRtZZ zoIZ|JLDBXB=_Qs6N1cCx(hmT}*h2z2v20uWy0htH-mcy+AU~Y>Q}aRd3Z8!cM`_eW`u>T}N`fgM%oX&jD4HZMYM35h&G-5f1Bf}2IKmu}X$i~(wjmK87l!INpn1H^5RN~42AEQVF-t6#MC zD}0u+t}+w>C~X>o&%QZ`^6Y0h3c}Xx;?(oY-U)rnNl!FZeIfDzQT%q1xPe$gj5TXu z#=(@5@w>7W`-4YUa&4j)=_*jdsq&h8o|M!^)Kh1h9LN_Pi`r3L!3b=(Zg8wFsjQ$= z7!xI#Mo~f6n{#(1tG8)}jU@VzU3|VABlFLTsEBLuA;$(oaty)~7US%gu#>w`@d8Uc z8FtLRL9D~Ap*FLwThm!KG6SfzkCDYs`hsI~r=#9k?LLpTq%g>zXGl|>KOwNOXowzd>u?=Q1nsbFd zNf*m0J|{+xe7c__`ZcBd#2NDqYhyPn?6yx&W~NxfExl`Pay5Rp{`##{Ed2<71m90w z1r$$#Am&`XO^n;lUOj?}m?74saS?SQla_|GcV*~eY^+s}aA&sb;Iv_UI?B)U>50@) zL+%H3V1ApA?@XXx%tswvNyS4MXHJ~EpOInaH90aG`>|?x**oILf9djmFIoT92iE_Z z^`GWA{K=~M|2{nZ)`R$mIwdQj?s4L={JddCI0o?<p?ToBi0 zX&XoUXTo*zDPX2D#gZ70@eCvJhT{V3_rkONLIXA#HYk)#fhj_<^=c|~E+L8%j?&lJ z;W|1gR_+m=X18(ny)$hd3QLgj-tyFNSv+1+x zh{rI_EQURWxuCgv?xL!XUql=H(_u47@hTT zFe-b(oKaqiSuFCr@RH%YVNpkSqM;(y&fF)**-Z5eyROONP=S`kjr8i!A0-LAV|UAmto6P8k{TBWKL=a9k4t#f0wR+D z?L#&ohv?($0Qd?6+aP{TELV>}T+@M_6cy2S&s4SCU&O4shy}nYrVQ@#^Se*FadKYz zXsvYk3asa;(ypkiA}GIk$hmJ(D`Cs~_k&Zm15>F?jPKy3@u$k&7m|B z1X&DCFCxy;$1<7Jb({zRAom^x6ze)beM_NJKxqW7hHYT&$<&9aTG-vJ@bFZTpOmdgy%d8gw892TBInydI5nPS!9V-Cw8@ z_c1%5th#iTncRO0?;`|&JK!AE%`Cy(6|cgb0=lfX3xzVG8VY$U?j&eIMVlZ1(Mp1A z(4a+@f?R&=@yV{{ZO&rB)Nm##KEHU`4bdV<-W#POFuMBbwd&_ya``0E;j$d3>X3`| z7f9yy$cvHaa?H#k32I-jTHVc=AuQH#-2ro2Hh%#VlBF~_5C+z zgydTubSR-XCp+wtXYF~I$2^~A{iUX&8l|H!JLuT`5izivA1$iHuOif01Gut!2Pcx( zc3PApJj#<}ZGOrN18C=Tf&_$l<=k{9r6_;;h^s+^;$gq{C@Oc-1m3-Wj99<2)V;ENylWe_Ah?4t$#*ZZ{DnxZ272|v*duGEVx?GUqlP#v-k-m z5E8^952#;&^zMSFwxUGiz@Lqea;q8yDrY)zy9-a7>bE|FVn3vrc{j z+1T_6PgIQ-rUdo%mxbp~eU=?Vp(egbNSsG^q;AVrcLSeaQa;S za`p-DK#FF0t1&Kcua9kP0QGI#(D@I1`bAPZy`~k z!^sWI&BF7%g!{tqqH-OzSQ5%@m!(%gn30tQ)4A&kl@aK=AIqq(`jnIBU3Is&T(q*W zOY8F`l0y-SLDIL@+$Ns9WS^&Zu@=A&T-#8%6;#(d^iV_<*l}@SN4ld>FwbmY_XIf z|CO6p>9lh<8Xc&*pJ82OSaBo!ab?QmE((7tCqoE&!l}SV1Ms8}Tu0_$!I*R`&^E^_ zgK<=a3|?{60g!PEPFEEF39@C4*wl;lAi|icB@%q5l@sh;1A|y{!?IvHZF5-`*3qpB zDdQbHnDWSjkUwo06dS%Tjci4iJ7Otkw;6cB)lMkm^4m=TcYRqeomM@GzYXq`9KtK% zJ|Jq&{_qs|#D5u2XWk{q=!*B^P63L7`E%5uTB@IJau#x+A=g>OMj91r`dGH_=+z5> zWloO|dnBG%v0<|PMOm`NB?hh|&0<+cDJP*{((DX4POXvn3*_{FGssCeF1m^E8=r$T zRRQ6qk_MvAPTo4(#5c&1krvW4T>^3KYkBoV1@3G`=))f@bt2n#M9ph_NF4ca{))=f zq?nEn?OHvUOcyHnfn1>WAaD+{bZ$8O6q7YPZHw<-=NNmYsw(Ex?N8{y`SCQi zk>v*c^+gw*+XB&YkseX9xtWBU_-_(oz!~{4u>r){1DLz*AWh5=kvf`Q*C;485+OUK zg7MXmze%;pNK&22&h^BUZy9{ zpDl#FfPuXvnn-b+jpd~`ry^vu0W_b~v}|x&Xv-~drJb%wlrr)0Z&KTG*BoIdEb$*8R5$?XVhos*AX3!e`sozp-CLp=ngd(~} zzm_o6(hLC7HUP`wiy8XTSmoK!?uXk6zbTdxzhQ0?q5_MsO0Nd5xB7ef7eje^wf?T$ z;+z6A_u#zr4LXZ-*-_@S+peBPm!Xl(I)_emKC$jA6|`%fD0@EL=dIfpcceP!)1tRH zZZ7<=9(^nUSxRi_81OtLdZA-tjFlG4xFp0NDeAGn*Gv`xSr~6)6FAJZ(?P#9xfjlH zF?VZDq=cZCkxF7&BRfc+w|2h*4uHu!>Ot zhhN<(dP(rqn%g*pI}A~HW_;>Ph%pA+h!p1DTWZuczCG9>F(@#M0_Oi}iff$X%cQ9;(4=={mP$V!j>k9m%6^9;*e4#A}Q{TLlJ z_dbcgD9QyEhSoUoU&sBkyId=&P}OiZx)gy(z9VVj`zhJH0& zYG09V&EA};%uSvBw!OOgv2X<}waM)e&zj0Uw(;DHmwh@58Sak1(9^H>$vDCP`e$Q>m;fESK?_sBlI z$^Ln2rLwQCqcehF=_Yb$drmVEJrtXukz5zVZ6u}d(HN-6bePD9QWi1MCcB^rzymjn z*eUMdWxNr(%6Kuk_lB`CaFvlc6OB$f`?5Q$AVU*B@`VW>Ae+1kz|%i$emuHgU+43F zT(P5zV9#F|MAv^4zS@^N09OF zG7s^z9SuzTo2%AE>uZI3IlsR+JcKHp8pJvGJ!M;MY^YMqyNqJB4N#0U-QxQvJ-0gK z7{;WQJ>IJ&c=t|f$r7ncwS4-8`du2^hsb{jp}>lN1}Tg)RZp`EY+{+pfrw~Fgi1iI z;@WOw%W+E`OLoqX(7bEmYPF@gyDOkn{K$LjtnGZquc+dwyH{$LcFFMbQD*;@1Kf%D z{W{FFOEojsL~|jyK~D^Kf)7p-x07&Np`$F~fTbz;0f`5@wM>m4Ypaj(P8NB{vT=}E z=W1UUtR}|@^g{y*?KYutU%(yc78#9tw)NS|n#41K)lEo_rt$84WKNH)jvDo=)QOs1 zdHM3$eK7@o6mqqV14u_Ug@+3~zQ1@mrV$Yjj8W(0a3+x7SRA1NObbGzphFhlWk_u> zill7bw};}(b0j} zx0`OfQu=Hj z&z*lBBCtVnsoo4LnTXN@Ub2{M{J_0&_xx%4CX;Q$?d&3Vwqe~^(Qc=eOU=t?yRk_Z zO1mg$ipz)V$R4id}N9o*CHBZYnZWqK1LHZ(p}@3}3!@Ct87_tmNj_r_mxb8@B+YtOs_W>^V@ z*B(;!>If@B-Z%(2%dpDw_!qwwzy7Lv{oh^n;;A>;K}HpFFvZxX^cbQQwa54J(@%a&ge^C-e2eGq3o#T(|( zA(uflZPQHdXlt&wb5Ic)Qy}~iq7DM>lu8vPF7mtR@|CIu9`a{~oaqO9pCxV{w20PH!g1s2zl=@^}Q6bgX#q zuz3jY6mBz=Q;0L^6z_E%Za>zX704c0YZPu{1-#r`?p^C0vW&J+P9CNzCwI5zyD^cj zMrD~mmm?{)RtX-PXuaR9prfd0iRg_7O6#S}S91gFSV2TCVQk&4*&6AwYNMeHw|R|; zs-D0E8R+)1mKR)T&JGVgmojeOPZ@fxJ$|=-f&qMXLK0=g1u)@BqB|;s-0qBOqp>VDX zI6X(=6@a^OX2KXInzo^PysHMza$P$-G*xxswxv$vtyMKi!y|649sbX~o#STv4dV;) zMn=6ulY4tbBkgaWPu_Rm`n<_m>(qnM|AiUNbc=!jXR zB!q|YqFJ=N%OlN1e{}vO$g!?(bQg`wW=`=_mq(xO?R`os&@E(Lynou^qiN#L*8M5K z*fA`U0`A|W01`(jmbmyJMCT!&n>LzGKL8L6HKS8AjNccGm-B5+1*ODzo5J5%um zsCnL*TPQ*{DW^tX&#F#s9?Tw9=T=0HJt{2r(cf4th}H2vrkpta&hRB^n_&OBiHzB$ z((nr@#UrlWZlS~@BZRuEh_M_*Nz1(&*mq*>eo@o{Vxtho!#__uft_Qy=4Rz0r&1kv zjLJvbBV_Pd_vQwL}HK0$`I9Vna)R^g*TXKv5)( zo{cqXQvNtymxNBM@4jU%qq(jTQppstf-00R7$?jEpd1)<5a!*Ht06O%LlKw3znj34gW8Zh z>jd^phbqbp^meui?YUnZ!QFPZ?Z){$n^e5rZ`#T6EoX9&QfM^?(%wcY5>4@%Wy^Mz z=J!9=>dt-`;@K9&pq2Usm05c99^#Ka=)vzH)a@aROiskF$L+?D%w?cu!K}=waS;PNj^WLuF;` zrCK`l-Tm0mpMg4WXL~8mC0V~ZWeG!lAi$iN{&Th1{0eIf_v2Mw)z zg}g~D%OrE)e*V%Vkb_Eq}1 z`lIg`8*~8u!Pg?eHbR{PVvG%kG&VN9A=jk^Gfs@5slKEu0Uhas+sdKh%XgY(QM-dr`%JT5=s925Yo}{YDF}t1Ig}Q! z^+Thkp)F~zVp8`HWufF4G#BA+vJ*=cZ{GM4oEpQSRgPRtgH439BZp(a*`QAX))iA! z`r6`v0_4qD^mDK>m|kX$YKQwwl+FD^3Z?c*%bBa+gEa=FX{XvvDayFc)s}pWsS68w zoI5!mR`dl)ESh}?EL~EE ze2m90QMuH@n%m&zx7BXRtuLp-2|ky-vcsI=^I1Rc%BOw{#zdw;<-;5sX{&0DCbuqU zf0Nc=0(TjfOyr&*4lvmrF|?gx29ax@5QkS)TiZuKi~Jj@2q~d*MfYG77a1%38NUOH zZIWrap~%4<&6_#AtoUFoZ_Yhl;MiTRH7C=?&p-gNR+UeJ?a&$XH#s3%VWwXllY%kb zd`nuP`2J$s*M(ZSi#?p8wD}3^?!}FQFg?MN|Ddy#pF-&k6V!*eD{f}mM-|l31IsWV zDxxCCYFBTrn&XfKKVnP6V6wPNy}z|EPgV9~I4ojgXkbFDC$A$`=!B!TE2XcY#|w|I zC7L|@<#j=DAWK8}yr?lGFThwRY1NzF=V&1ctR{p}hr_eLb^_W)w<`&CM}+WkV0Zn3 z$-!{7#;Hx|u#MAr`H1E!he#G|)d+;Jql-JZ6OB?U=T7zILak$Sat%7S=-mUKv&y@5 zPrr3c3CXN?lIk}99EZN*McRL1=TYbWQisW2q9NhIyp2$PH$MW}J)QvV=m#Rv@7wC! zjzUg?V_5pQL9|#2Mcc^3zh30P8meFkHBRg}-#5JeW)tHF0bxM$^2(@-MoSF*2b3Si z{lmcfgjpz!X>Z7gs8=_)IB>(ZY_zpvxmFi+pdJX!L8;&Y6bR;76dee{4X9gl11pl{ z)ifXk3wf8eqo$j4g&J<(43i0fYV6rA8FpUd=5UIOj+tHfX7=>QoaCL|I)zzDvnfGc z&6yL{+cY{!z9m-6wa9VOYd$=l`GPb{2L6`kAS918Zcsl5S>QEs+g>t!@haHvhGwD+ zPPG7g!$+m@08lBs4()EjZ?EW0wcyEb%%AE4CS?zU91ppQ9_@}_=BYdC2IRf7eV7$u z#tKFi7!{?}68*o%L|N>i zx(7nT>awouK6;jIHXFSSDNRkICBelrp%3~z;y9%TV&hO9GYTGSGqO|$)bqn~Q*~0( zf@u?rQs9OZKpS}JW3UFy_DQ^^sH{d^a8)STTXT|6zNxmWa}g!qCC5RV$VC^Ig|5I2g%qW=$dTc>hWc}{wHNH91aU?K=>85X z!($1(F=jvh)=B$QL{k3>#Qe6tZxS=hAP==tc3tU0M|P6wo!8%W;EKoEw-BY>j<@x3Mguqa)u=|x{lJ0$K?lYso5V+H&>yy$z{!XGeP zGK*gVi#FbNxyWif4ilalk;Pkgw>VH_*+h`lRgVX!0sMAuJSp5=+hDoSup*KBE7tl# zeoyRU%}VDD$TSO1fzE7^*P;(@V%xopBj>WLE#wNeemUp)ji;iah={S7cV z`c>o|*b1676gy6yZ3WJ|yHH|XQHk*yRyt5A6(u-}%JGU;EJWbe5e z7NTFcVl&V9>WLH?O`!=13+>K)cK?}vJ%;D=OH5}U<Tv;DBWN4Oo(jfK zJrq}h*^5ZMyKKtEcr`sgE(u+4VHcB9b;QOje3n6397r`jTkw&xADNQvvEIC8r1v~2 zzhbz{TLcd%*CEttA>7H3CY;m2W%BomCAj}9)j5R?QCNt$yA zWD5JZ%qG}fqNMR^H)I5%%%(mJCgn|A+0}*VW;dMR89~)eVp*4V#hpIrJZuG4N0$P- zr`#CCuNqE6-dUI-Y-$fG?VLYW<9%VGI7fpVwWTa(J{WENP2%km&j*?fr+e_V z0vYaQF6fY6(w*!dT6HciXs|CkUwUvq$-LH%lALNPAeP9-CqZphVBL6iKs%H;1-vje zG8(Mo2zJNp7T(0UL!+)(x6UTdtjTlJhPioToLx)Em~L@@9nA=G4P(0^Pjvg>EcrUp z>~&F}DI2a|t*EIIAS1O*YdQ`w>v|tnUV7d^JjwvLq;(<;AXCg;`IyV1+1VF zfYYvrl`@++_O4KiZe$iTgyd~EJiFW;9i_AAqUr!(FfX_j1qEJeDvUrak>N%w|7IGT zr(b-J1bGB{6<_zsp}AU~(eZInJ!?sZd6+&B`W2$?68ln{A=?TzYtD+^LEbJ`E z27F1O9ZM=l&Lik*<>8)}42B>)X&G@Ob1{=YehKm~o zRP^jSZ|uFxN_D<6IO*Xp{v_G|>#_3voveKgc1VQNZ#*UH@b6 zJ5q3nA5kW4?@027zQ*4BSsm8*gL{j=m-B=843B<#KA{dvzsej``@$y7wu3viLG-9b zCl4!VVwUMGYrAQ4-`&e~n+Y9F_823m5bwFI=HZmrrcy8T*BrfEJObTrX--+j5q%hi zy5(()H>W&ZdIFvXX(?IbdS>h|y;H2R;5dCz_sw6TV=RZ-j8B6N<0#hA3A(Hs3HqXr z&_jCpyMo-dXTY_i7rqeg$oiZ*?vj4B{Pw493#~12HC8_E1;%CSpr_4J=p-+0<**sd z3#BQaEYsanKkpq+ip#Qg>zYi7*A!#iQrt*AOzw}!_k?jrU@)yU4sZG<5x1KApX_wgfU@b=*^ujXT+x7DtWusNx3Y`KW|AEPsAFMqi=(ltq`vR@+pF+j;`S zFX#z$PKaF%msO2Ztv~*hwReA_g+&s5f2wN$KFHaCX%$LvSX6)Vr^q9JyNG{;tn#1F zEjJapi;wLDORG2%Y&x|jw~o=!UrdYsHATHWA+i)n&+Dy7WzBtEE4>U3B8UYZ;l~uF z!Phe1TcBSfac+&Oz4&-qf(Q#LlT*eIR}Bzb=)!G+ZxVY>@_RtDsDMiX6AC8pnD{)9%T8INnWBm=%5s1wQ6g|4r<&w>H<5f@5%AWBH zGvPs&Cm5*A?Yxobd&U^nMxxwXodxD*G?5#BG9-|n5oR5^Sa;sa@o9VOQ42c~{BUK! z=kcqYUSvtUNfOeb@kp4(&-ZsbAV#b#-QGAR(#?D)NxUKcGjPprLTQ2V3{1{s6TTf_ zUJl^g>D-!rV15a3DAMA?SkFturZ07p&R$|8fR6U6(PxFj&1h9-yfs4Q&rkV7T1MX_ zpi|O!a|H%zCo+GU)_9klwOTaw<#<7G%m_0#vqCcY#%son$RpN4OPAa9<_4___EgPO z^dGa~Kjj)?F=D9{(X$$WWGPj@iMZmzj5C2laGo{tw%f|o#`!(UZX|&zZf&PAoK2Qf zkHx?P!w_2_QiF+FH^n{obszJm&WWy{s!Gdy*Jeq!8{q2G_@xD}NopZ3f!01bzW1t; zwaXXtODbIKfI9#7;k~UY9L|oU;69GlvP+(T0giKC=jdEZ*!znbk_Z+NxBb1uiWJKf z_m-e5P6>AA>PeR_l9ytbi}Pl9X;ELaD9mgsaIzv~|p)OJtFzoZXV->T*yO%2yAb`C`7A=!x-=Pda01Oja%T%Q`b_9C-&rJY1^?Kb5>rZdWvvDo) zRx3Pe%(^~gW5C+^zPf`Z-oRffp{KW%fmcscpuhl4Nn$Q)n2T}@+E3r$-5 zj#;)eyXanoB1+)b2)9G3xlqbykc&2k66!#)%0v?KbSE<}p46$0`%FQN)ykcs_WI5i zO{8tKjGdfF8{L)@qjc&)PY>znz`GmiF8=0kMpJzoPh=PdpJ%OCue#%|vOJ&Tf08}% zihdhezApMYaPS@i$$_08kie!XSkm;*jg^CC(l;&7Y5jDLn*&Y zM-{oCs%QnIapN*)r39NGgJv$ylAAE=BhbOR zvlWVjp_J4(J?Wdsjd}@k7rlAbzDbS@O1iXUT{y|R`Ge@0mE9XJ_{YcErNc(~FM9h5 z`?U&eThK>a3xX(bQ`By!9?UYg#Cuq4GHW^XM|1Qo;;q8NP|Mf|lGWeDjHa!F^0)$| zVHkRJHI%?Qwys4@s&B}=XLhkjlS0^p&1^W|rN28DZ5Tu>Kz*8TcK678KfoLc33hm4 z@u=A@*6#k}s}+7e`hlL;C_^?U%}ozkAG+_URCD!VQdw11uyqI0-m)%J5;QJ|l9O(0 zpfDDE6C_<{qQqcz8y^~*TkB=$7%9|ZjqHEF1(WOLrq-pS9T2zM=BDh_pc@=iRy4e^YV&Pc5YX*+u=&o^SsU!}lNA z0sbpey+3i1_9xwU|2Lz)H4`MHzg+$f3qhe@7{kNG{F{^NJ*zsA`8 zHF;1;EE&uLR*IZxHvBy}bgrAV=k4bI$}@|^%X!fi1KW|W)DWEu=ouY#XF5X(`e zAfH;}&2_;!a2@LqgJk{Bp0IJInDgvz$cVG2+A{N#fE(h-6RN>vQ?;!L#-ht`R#Pi`G+o!pB`T(S)*qlRfGHZgTku-P{TRNO&Fuy5*)!MHPP1^ z2ak0qVk26R<#D8#@;3Np9K3(QGThD;R==DYnalV@>-7z+oDFExdlcw;^gWc=Jz-tZ z^Q=q1r{c$td+mNW=c{vgB79fhn^6KeZ(-y&HE@66Xzvy~hFA}gTGaNuOzCf+NpU|_ zvTH-9RYHnCRdnHua$UWba~d5grk9isHn@8lKNxzIp!fFKk>rerGFI8?VS9!aoXcV% z6*O{r&Yp_-%k`HPL^Q0=iCqGb<@N-rZ&oGz&+ z`)|6Ta83|ZnkXr2AM-HK&e2uc@yU}Xn@_T(W1n)@-K@ckx202}iF@@8^M<+bXAn>%hNm10UUpB;_;`Nu_B<@CXEU_k09 zF!iEsrE{-6;#r>V(NDM8lM8vW75sK&;K{ubN*wi^S|a;@uv)7e@h?!5u{AWI?f7S>W`vKll8(2 z&=fo4(8azQBX0Vu%ssr%W!YXEt}gfGTxQiC4z~!?`5{oHdLyjjQlZ-Uebe)!3fG3` zfBNapJBuw3M+Rd+B{X^r|3DBZW-zznjA=TE#T*2q+jyKiS9LUp zy@k{su4fn=N%so(JYUi+J~l-&;`JyV9wbKq1~P2(;u+6U*#WGJRbOsR|4wQ_KpEb1 zSAm^*55IhBo<7!!{*cS0rBAiNEQw^~3o}kIob!~s4X^Ia+>HBw*n9J+rm}TkR7*=# zM3h!RNZFzyq*NNENy-icgh(R@5mFW+ga|35ix83$q!%ecprngP69F*_1e7k)mklCq zBoRUql{T=V5LS`KH{JWad+s^op7+kZXOA=X8{_;XB96t%nrnXF{C&U17NU14w8fNq zh$ZlkC7<$(1Yn1s>^PKlD=k!@^fqYmQmt5nvaLa9sATzq&;Gszgql|{=qCGJ98NVg zIi8;^b>+0*?d&WQ?vhrCVuCnR=$#@jo1&i(Ip|t#nHE;DZc1t*vmIE=(#VXmcw~Ae4^l(Yx*noGR*R(cp*!bKt zmRS|BT)<3t#vcvtxqN-z#G2|j5KcJ%$f&HaXUDVaA8a1y2cEK5u}4?ctCWd*2O@^ zJ#^~^`(3}>NaC$jD_{F^Q|1z#;;mmNOaE849RCo6Oo_kLHviXoWl0v0q{P4mUst#z z+jST{xWd+)Tcz!+4p$PBZfvKMMIs_gbDQ%DEC-InB~;3eG%-lXTMvZ59ibi^S-Kc zO=CPugpQ(*R?h&Em_#t>#n4~_V_FGd2+~?vY3O>@>xy+G{|k(Bugbs*^K4};gV`Q8*7>pX6zHsHuReqI*9DO&piywYqoSZ?;rka>&w6tS9)@| z7okw?0sVDe%|~w?nYOp;0EXKxM0PRK(6t`3PoygquX$Rg$XEyIF%q%^r-wqy!l1Cv zonoanuw1MTZYy>iXj&P**3-n=ql=SPCBLb^Jt3OFwdBSa9|`{Dai&Mgl<_?ML{xP? z-Rb7;7jN=Enu_-tr`7=Wz5^`}45g_fzCz+`5#X7OpikGzD<~F}ess-z8afF1n|s4t zn)D2OADN8U-1NQJ{4@>Q3=K2E&+4Bj!<*ZIFVyhLLPPW>Qm9M487HDNi2p2X%0GK< z>OLM^b^XGGqpSP_UCCYBH8LY(gg#O^8d-yOp&XStz-cAa)?cU>d*hce=}q`DvMI=; zTM{o}#klrSbf?ZJ4P>4_oaEq=cJ(b1H<4V%maUaN2N%k>$1lu?Y}y3VF9gX|rAb{S z#y2PPOP**HN515n4UOhuy|2uYOkeZ#sN-~Aos!5BYCkD229x$z)N10auTU8iSN}WE zof&05$7!Mt%YGgW8~d?kSoUkSc6u4fzujdjGWU#^4wvWEvzl}6GgtT3%wHnMoN|46 z6mtiCf7lcX7s7GL!L}rO4KJVs^7NJ!6gHwJv4fa`S`BAOPX!`s8MDtqN+y>XtvF5c zMK*GA9;6Mo7+mX!T8eMNG1~bvj)q+*t!P)%LH+HlVc((cO(|_$r?&?l&V?g>Fr}~m z{mvbFFUHB%;2M3%Jjf$2^7DJy9L$5d&oITjPE}0>0I4A_#unLX@dt&$FcGCm-Y(Cj z2BfQ!zlRv@#MR0A)b+CwK{(a&A#XPv!~dR)b$pB25V&9Z3F(yD>tbDSLd6wZ+zCu8fyxaT00`Wlqa+NxMj zN^a32r3!u0pklu0Q!_tAcm*HX?F!Oyn@oj9dw5;BtLrSndz04Ch{nZMQR!UcM?SrC zYwd>HF}YWpwy{lch8Z`58KWkP-VRjAu~H8$*#j=;{6ZQsjn<~1WsbMdBlHf+K_

  • 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

    8Yj+^HVmQ$v{>)UaH0668k5*5Fzkb1RBR!*tO} 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 FO#lOWQC$E4 literal 0 HcmV?d00001 diff --git a/docs/source/images/cloud-dedicated/managed-permissions.jpg b/docs/source/images/cloud-dedicated/managed-permissions.jpg new file mode 100644 index 0000000000000000000000000000000000000000..15369112b8e05b01d3d40c43c3fad2eb141b8e72 GIT binary patch literal 79395 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 literal 0 HcmV?d00001 diff --git a/docs/source/images/cloud-dedicated/register-targets.jpg b/docs/source/images/cloud-dedicated/register-targets.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e062b3890cdb564d79bd6acd1070ca612b9642ff GIT binary patch literal 125281 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 PYfmGn+;5uubMn6dF$h1P literal 0 HcmV?d00001 diff --git a/docs/source/images/cloud-dedicated/request-rate.jpg b/docs/source/images/cloud-dedicated/request-rate.jpg new file mode 100644 index 0000000000000000000000000000000000000000..485ab7d07b44de7ddf13c9656f2cbcdc5c4d99a5 GIT binary patch literal 195784 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 L8BEEB;r~qlk1*^f literal 0 HcmV?d00001 diff --git a/docs/source/images/cloud-dedicated/resource-principal.jpg b/docs/source/images/cloud-dedicated/resource-principal.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ed80e5706dd07ff3c0c71dadd002fc063642180f GIT binary patch literal 76432 zcmeFa2S8KX(kQ%c7~(xfR>x(X&D(nLfoR3RcYQXCw~@(S0`?pWK!hX00ubjF4Rm$`dk)&#b8TP%ub;5$Pf+BOT-tCZ z@RV!*GXKp*+Cem%#5-hbVF5dK+`-EBh~>`?^1kvqe?DlFA^-%3gkLyreNfTG)lHFi z7}x|z0|I~yAmHU4cHaEhu_GHeH_HCR{dYI&zy=in(5L;+^Z%~!KYkJL@eT6^8Nml; zAbi5SgFzSx0Ng3w=P!f<0PhA}d!oY6Z@^|CEOr6xAP67Zfc<}geKz2;zrbK!u*}Kh z7GRk)5Ek+d@B;IBZ-KDZ**~QF{{jA`4`2zfuC;H7?*+KG;s!5{T|oH3gM5Ex{BrxB zWdEV$e*^{xMSwK_ycEFumaxDRcHrkukoK!SUWYbd6%a1>_Od+jEBql6?sW85`1|?r zgU3M_l$K3W5rL=7K^T;)O%T5eR;NH1#Iq?NAj0NvaMs0ulg?neD46~%5Mj4bR|16J zgq%I<0Kyx1CcVQfK)wPy0DzMxz}I$TyyZc7=LN*^jWS?=IIVnq4_Sh+76_k%hufY6 zVX!UE+_1NP|YY*36K#>c|b$|=P zbqGw|%Vqi-?qh$TW1~OwU@O1i2?bm9{aMZlq__p7EFACx??kW!0tovJ!{6~DOD1CH zFFcC90E2t?WRkm3jZ(jt?dN)Sx^GJt>JL1FgSY~JEAjVSbNHX}p8GTR9Ctr>ALbtY z4TmE42=^%X8V0%b`zZY**Ehy%gX`uXO+i0LA{e9>4pQg)2kNx{4#ywyA%1V~*KzzC zMucBTmdr0)*x-O~;!)~RAXe-5^1BCjFYWH%eP?&+?k}7DWlypkhNF|3>d0ISR_B&_N+tA!VUMLJC5vLPvfp zr6?pRq$gw}qz>lD{x&+lOS9tN@c|CFf;{^hxBhus8#4p`8zzv~9D?9D!+&q_@8-uT zu*Yy93dDH<`v-(8>hIodqG%4P zI$uTG5N{nVMX#VB#h+PWiWhvtd@n@$`se@~dUB&40IVGUssA`6dVWs}w+DdzUpLmh z-_zV80H8b!03;26PumHujpA4UcxLP!aUt>-e4t`}2LNGy2Kqn0b8I;Xu3h77_6oR$ z@n!=6^BS8?zsqJbOF;ai0Pr%1{Sw&9$I-{VgOg(iuxTp?=T;7OI{>N{4sMR0*RO~H zj!m3g+&sK|{F?>90<|KbA;QVIiHnn)d&7X>hyn8fuC3gnN_yrz+Z?@kcZ7=RU%7UN zPx)X~i}>-6WEF$67h?H0OGrvd%c!cU@7$$fXk=`%XYW3XLzY(7HnxXPoIK^^43g*V z9I1K|9HEb#sdW&c3e zR*L_-d@C2Xk{*w!xg)Pv=(ZjDSNOyZUb|D(!mn&_oGgC!!pF@L zDuzT=$_8maDf`z5i~Ubg_8Vcp(=`IBfnTWF!~ynp(x@&0=8 z{k-@$E`i@JHi(2{qb4UOH~1&O$HVtq-oFg6$3TPg1e*YC;p6~?iE}Fe1z2Q!wc*6t zYATDSK(wa%6|w;c1vA0P(D)(t^<@b&|2`Y&X@sr5WCNR_zn64=aCdPtbhrS)pm(qV zlrXu3ZeY&_ut@y!6_)tL6rI1SZZP!!YBt^5=T~slz7g|Nc3xO&Ua|gzjEG_U;P{ng zNhTTEigP^rmoWV`asFCg{#r}_d+3c5_u*v~e=S^pY5f1~){QXx1MBpd?TC-1cZIC9;2Dk~(+MY~Yvmk08jdLpXv8G4ZDe`KPnT3z1y|Qh6 zZQ9ba>~$%d3|pZ^t8v$~;NV$h1$kB{lza*?JjmjwvjMI|GIWW9y!>+9kRln+u%pPY zv}u-|TOZwbzgldN->5yi^zJxc=`khE?VGQC^?M!Dar0K%-fPSVM_3~MX(B_yj}1&= zmhL@ZwX=a5-Ik(Dll4hFak|NdWrMgK`Ck`zaCF;?TE&i~d5v&PJ5D!L^GH>OQ9(;I zmOx9Tj?re!Oz9@99+vJPWE&d@W&>WYDT1XLntP_XI1SvzdamD23_9X-$X6%j=&lR9 zpVPZ7F)G-nk_@p+)QikS=viHYDfKZen5ZBXm@6+wt1!ksgpVsywnX*WU%I5?SWW1r z`iQ)I(ZcsdB|Wp)YLD_)*cA-<^y6h&^dOp_c@r9dz2d1(v+$)jZ8M3Dcz14QSI!CU zsLrRY*B-U@3O=q?%fB(kd3n2$36CT+<^gWDjrtty{1EE{rV5|@gAIr?jxleTIZL)G z2!81esP{C=J6V6_zU8eJ@pnzB2itHlqDylT#9>lI$cO7a8LmxBvqi^=({ac9+|zg8O<`b})zHcNXmy%2-C_!y8MGL!o#2=l%{^19KL$iv@j-UpY)_VRwdc&MWn&QZzr3L zMbd9YO>ANVla&hFA-m8Y$JLm*&5Eq|7YDDP&K7eOcCmzdYqc-Dnn1>O_G+65Cs z?__;+V^uw%dAC56C_5Gi?e{`FrDw4xvk5yZ7H=rITF9Q~z4?B46a3V--Orgv9bs3Y zTcDHm4W6}h2>JtF1icTX+eEuW;iaCpgea5aJ0FTKbgRCKsCLnvO7`|LtGYf~rC)jK zdc)J4Sr{M4g+}>3l%5XZD-Hhb_~BVkvchEuWX$3|GO&F;w<2W49<$>RpT}OMmF72o zHzYLk<@F4YsGaOQsbeK+{oUFUEr9NyAiFDUMQPD8DJCt@r`9cnxU_ZW76E<)LG#mK{VkVA3BT%fu~6LLU-#-o5Q*DRzwGulJvL zz{~#liw0mEWCL+mFh0Trb?O-Na%Ky3IIeAioI}I1MD2~)z#=TL?kO9vu6MnfIpfj2 z1-2_<3VjsGgFnCq{4$5as7IJLNcLfqur{a=(!~8mO~yEN#jbBMcES9ztBjAww8@qm zV>QoG)$GmN3z`XJZIoP@W9#>*c9kIjJ410`N zZ$BPVS8ysbY?rK$M%(twnv^fB?M!eoiLrr1V}=^@IvXH*Vme}o*fc2l#yK|_wJx8Y zuKwz|1GI+@%VGnDDP}d-N@u^41L<*h9}`SRouB|@AFBmZquT+a={P0Q9V;)l5$zb- zP2?h0LtgHq594DM-=fcszSXg9pR*{p+)E$bjv|8kC6i_iwtOC3GDB(;7X_yrVjHYe znx)%F(O;cOg7@+8V7cb}$TxjNW2WQb z!b8g}zFN8?99x4(gc9Yjpj$&S=*O56dN?qOnhv@2V3S>;>wW%g;n!+|a-W>%V6D*M zRMzH==DC;^c;AUMXstr)k}eU}h8UiCqkX)SC3kM(WZ~&zn+i{fWJQd=(Y1=;5uc=H zx8-gFk+^kV<{gZ`a4f7A(I$Y8Q>f8RoTNY#bnhiZf2Sv2Q;yaiwUt&=vs!c6w7dU{ zj8I}J&D-KBc_5CjuBz{L27w^{dTYn#tCrHQUmoLCD|}dX^SQ%hJ+%U4#bGwka*DN& z4YV$im)l`i_a(Mx${`cmXHSrqGkqzaoCrZ~JD*$GnFgx`UQf!ty(GCwZ}a&(uG`)+ zQz)24cX}j41w>QBkYd(CglU`mIw6v<#0FR_>ac2mMY+$%d-jykw@%h$``Y6@xRe;J z(h%5<%@*gw0C@;veEdDimlmbly+6Edb7DU+MlH}rx`}2g-dW;C-J65XYQGlmX zRissbSKlPztp4Q%q2R7~T66)7@hhR~m>`#t#K1q;Z}2bgU3`vIJT+%Mf=av4N#@x*bILEB zlG)}4$t&%as0zMcmwM^`NC!vC=hOQ2Sfa?;r@h#2bJoxC zl_Oo4Zpi9})vI@52ntie46z()9{C5pO+gNs_cDh8rNs~>n^PTwH65VynxWBQ0Kq4F zS!fgSn%jXl5Jy-QYbWz2i<>q$wHnU`&gqH;Y#m3gv_v{zM5jJ#?Bl7fZ$6&$=#Yv? z_QKnH1^O>VIW{%TJbbH#QJ$!_UhD^@7fOo)C(lCN#-LKz|d8YTttg9 zcGZ(5>WMG3kB&Gr)byL>=LWtiy?NcsFi*w6>M5$~iK&IA^N$Ei9gN~MGy{`{CEMxJ zb`F9z-jKu8M5+-&!2L8TnE415d>8g*T)y^G`GBwx4P*2CQYx}w0iL~!pr!FFdFbhN zK+m~rA#-UjeJjeJb_XOzo0)Ai!H+y+(vo>)UnDN#(!;{XCtY+)Yej|+Y8N=3pOzmO zO|VJX>AkW^2pT$9QWT#_5+F)PJfpidzyZMum|Q^HrF zLJ-*zq=YOj!p_wA!&j5j?%k2pRZ*>K?wV`nE{>_YUYh2?S&0F6K6#zFo1(!Z=4c80 z_5L#tFznu6H$@v8qrcw&uX(`kW36GT3^8lp6Io0g&5@a00($vNp{q-n)|$DpNFINx zS|%6>0Cn|5?S|w3_p(k!VjfrW|5zb&(O!WSqr?XAfh_SdOUW~Sn6m+FU}avINr!=P zfo-6Q#M)q%32Y!9{?T$s8aq?~WvpAU0rVhaC#(G<8<_1?pi}Wgw{XY5n*KkR;k%Be zmgMBXe~Lwg#;(&_dj23eVt*8xihaAr{t_}w>t9pruLb3=W%U1-%Hzb{x!H9c(&ZZJ3G=-t?VdL~7|B(PWIJFbTf&@T2cwoS0MInWMZi2m>i#7bkP!RzOAdBzkp=o|W7Jri$& zK#}U&91PmSVmv+-)lbhv{-|B_O365tFune!Oek2=MB~M`rpil+e{MdL=Chmt`z}Ml zvn1t}*}!yBj1oKw{=m%=48XQz@QD!p>>{Hfv^X+#?)ni1mDE?5uvkhF=TO; z^*hX;7!4)nG)rSX1a^WVbQ%fnc5)-WcZgvENch?Bc(OXni&=OT+_>nmftSu}3I=ST zO&z7r25t|gvjOrmiUJ$Zn)@fL9PATwWR|3WHG9FD*tJAz$Tk+Liw$tVKBGW!{YO5R z{FzGFVQZ}uIy9GkpVQ*5Wu3R4M3yi8?_lKJ%%$zl3|1bCiw(Sm{@a3kHU(M}3R_u+ z(ZERCZq~b2OwUa)NTJEd%m?M{ADJDF`7=Mi%%}Vh#n%6y@cO?sP_-({>0Qch>wMc)(CWBu&_#laR zS4mfGi?XlawP&Jto9A(v5e{qnu^gD8YhVO`sY_1@SCk% z^vRR^Yxg|1w6pwpDeIz6K^@b@xgE0^EgpcE{%-Hx)eIRx*{R)TsZvyvBp@pNH6!8m zeYJrv?80rdz7pdPT5R5>q~9*uo^2oV9A?6LGx6<6gaduM8K{WMmp?T8etFhq3jN`0)w0%UAqK+%KpA?c3oy}B3X3!_dAsE{Y(e)zHa zQw;R_mMcOGzqE<$(bsMoJ^$tvzqIec66NAR!d!^m`KJ)jbW3oeftH22gA|77ivuT2 zYbMPXkpTTJMoDBzxUm6HPioF@o;DJeqbb<3KCt=+f`ai+&924Fj9OuR=~iYq6D>2m zfwJFXNRM<${;GgZSNgxm2eB{+(RXMK&ysd0W-__Wyg)-T7Z2K{o1w%T%~EXO!--A> znrk2%U_8Nf4{H5OW{lA>CUhf-hrM=G5Z`kb|MCZ@H!Y7$C* zGqD9Tw+jr$Xo22OmWv~(wkyb8tk~k+pn22{1I@tr7+JBZ9+`Inyw)5yu74J}C<6cf z@ARf*OBMei)r4;X+&wB=e5OA5oV@<;R4?863#Z%iNuQiwTP|bEoB7FQoq1_iJfh4TDIEhacV7!TScD*K7V{mkI(aN`SW0c zM$4IgpWpn8T&-aKG?&HxEa)&BM{9$x5+0f0LHs`n z@js*cV2NmZuc5}vhRcU%vxLsuthO*7{2a*@?0-pn`g_mblt_*P4&T~7nZdW7lAYl{ zs`Wwv+&KIzi_G`dXuY{Q8-Xb1&edS}{tNVkgu7D}r?F{$IQoYuiY= zjN-($9=d2FxZ>X%SHRu=GTW1c|8`M97`k{E)H``dbaNce4@U;qYa(X-bkF8IdZ#)A zR0Q@f8KB0EU7{^_vNkgl1T*8xa>o@!0;z7E4?g;AJ4Q*nHZL5h~enlozR zsNi-c7IPX546DPa1&Qr@DT^2N8ZY6O6#4q&FkM$_)e+NpQB>{AhQY%IlERwhFs*PZIN)wFnGEIT z$mJ*C*_|$Gk2*AL$ulbN#dZYU*mP+LcBxI8C6vIk$89M2*maGtda3#)@n%WHpu>rk zVlCp^NafwdIvEmDNk{Xl4_~kwezQE`{G++}2VDU?DcZts7Bz*DVYO}Q>NMyM6;Av? zAJesiU$CjNxt)J<+v}6ruHu*m!0{#cXb=$lf#FHku5ZI9vVo`S={Tc6djryH(%IB@ z-8-)16AOAYZ!68{2RHBZ5sSa9zSpi0Q1RLMT+0R+Tv$_>(DosoReQ6JSgo(+H@e@W^6tICOtHlgN&Rw7CoaWQ5d@K zw4LYypKs#DE+1;{LXBeMwQD$FlDDRIktqEX!;)_4*ELPB*-?69D)$L)@QhHPUBR&w z`?Y&(k>8-VVDZoz!JaO}a5dGa*UU0HG=>CCgvx0*ZY#HsMi||D+dD^q;N+UxKb$TN z>s)oR8lTQR>CAJS@0AgrTt9{FTu#IYg+TaNJq=^HtBvNADC#ZR6=F5X^o1c_#-lun z5dXQ?60vKmZKz`X*7m2q`t6fhn$+qpJlSD+Sd#=xF~Z6qU$pk9J;r@mcTPd*RQ%BV zVhgPccMpTZqqfG9pgT_0tEul^T*)GN{D>p<(9{MOeWzeTG+b-L^3~JBwC;BAPRTDq z_hJMrahu*z>BbpEw@zaIaM98h)o#6*VWXL1ygqbS4TiQ;cgdN|NphzlsA-h+%;ZK@ z@?%mCQnC}Gn0TbVYF}j z3glTeuEQ?XL!BfzoAd)Jf^6LxyhBZwM<)~hXxOs8TR_&Vp(DNI@TO*(Z=0wTwjYe` zP8Lj5xiW7u%<1wINNog)o7CO2q#e?`!1@;0WJT-V-Z?{BD>KPTbjhgSTx#}8uU+e@K$$Zup#IvN)COinGY{in-N)|=oQ&XTokmTabnf1TB{P}r zl8~6i^4|6Y{_BUHs03vz`9*CJhsLn>vf7~4QA?^*d?;T^;gL_ZQHNr8eWz3`IIY`% zj_jFfufG^>qBnf{DyDGT!8JvmSAbJq67(!)II{yP+=wApdyspuw;7HDnMsWffz**& zdSt2P)BO7KR-0!vai8N$9CE%g-erkhTa%_ALyv(+&YERd16ik0Vzj(UWJ%ja=XQi3 zO}8B)m)b(Xv>Kg>a9s-i8muyS#1k%Q^YF#lef}EZQGU3Z z=X-?%Rh@bB2R5!)o5uMN>Hn6TnNeHVBNCXa5d1>n+$Y4>j_)hccfGVOeLaxl6Ox3F zIH@bfs}Gfgo`VwFs7!KaI{hRgh6bk?cUh5F7gtE8$nYM)<|~0=%zGhPhF_lFZfMNP zmoTOuy0XRQ>ErAp^k%*M3V_R==?CUG$;vn8RbC4)xx1tI_P229Ar2g zOE8EQ83`H9;Z0mMrsyaJbamhI$;N2oCrcH`;OS@y)+kK0HvR)@7nu#%_AwlTy~<#; zH#4)x<#)us8S!JlDb`eh?yDTRgurC;D~Gf6?_Rl|`5YR8$-qlA1E|ep>m|;~)Vayt z8jLtCi1xeuNr!Y*T%(b3GGfm_X~D$7*two)Wy7qJ7L7IAkZVtEN~@op zc}VXj>C)5_7ZXXCxB`=xAXfx>coP_=l^)0(J3DRXW7UmM`*rU>E54MZd**q@SL1BE zhuAceLe5T(ml1Od+pwY$p*UoAKWeN!R*--2 zEuj2pN~BL(wU1`e_Q9nUN+?U1u{rf*A0z4klJjK$k4tjuM;bqVx1>lsjE)ZP@+~S# zElpKfi8r;gdXplZ^il&MWhg zZn6tm-J$np_=qo#FW{99jiz*X2v|+v@imf*6XZDR9kM0jiXfH zk{iV*Gt&sTR-D+vH~2uE=xMhFx8QpNsTh;&lq^G&oQm>s&!N#HrInW6C=KRgC}No~ z+lAS}5~i7w1o5p@+MV0T64F(f7XeNU@uLt~dn;KFVf$Fw%TIER`?|uyv{Jr33BHpf zje7<@qk*8QgDd`av;YlHJx`M?o!bXZY&Jrs8{v`~iYua`jY#^nH!l@IhDtvgbzAx+ zrSy)p2|RkmX*`L}qb<|9(cQ3`$W&smB*{7PzQtsc=b-tEUL%2b^3+y>%Yd|E%1mp3 zn#gMzjYi8iyB)7(@$rVEp$uhaEk4A7(25uyA?C%KMchXUyHGlC?e0*qFA{EsGPk0_ zXu8L0pQbEynkEi!y(O)H)mPQut=IfX8Qg>ur=WFRNhm>b*yMJ%AE3WM&2uM3vfW{TH8-CL#FzCf1OW$=HUV?xo;jwaj=Q z&^$@+Cu|0P=!(GyFGfCo;Id%6uMVe`<9XVB!u))mWAw6SUb^bm$@r0)oj{mQmlu6A za*BGHmP*&8xq~M!Yvpr7OOW&N({*Ly{ZEJOOonyt$I9l`JNaH6ZP^}nv!zvf_nuA7 z&u|c$Ga28)26)Uk%NPb^Q4j0V`B-zHx#{_*5aB}Q!!ve;&;6d=$RA6Ft9ZXRxUBgh zKs8>>@jz_K&fA;*6K~<7Kl|rk@(b8+mmuJyAXUm8Y+xNmT&Hh-yqmTY6UPP+H+`}4 z$_xzMXHzqRc?19X<^qZPr?&kkkpe=jxz5a z(46)g*nPZui&@b6wO>ayR}pz4)YMk?$@JCD&s#|#FZgKr#Oi`8gsfJ7m++&!&5olxk1 zropcu&vsQkTi2LmTbi~azm}qmYBAwfUeG`UZu*K*g4X*lRT0x=S(|rNpa+c!*dzvS zxWw~AqluUA{kipf<2f<+duDK{B1cFURCoB}gh;$G49?kP`hCcKVgQ!HPSz27F8>qzFbrEZLE8!^tepcFfx}AM16HC0{0bw_0 z9ZHFqDGffH?>6E<;dREgHSZ$_r@t$A?`w$~S9m^XBygeGNhQFy7g3(;bV5Df@W2yQ z8)haAbZ&CpW5zcd(-OKn6hs@9qaJvS%;(A&4aDyAkuEM0y)kWJ?ky!+~kbk2rmi5X{7f? z*MEB_vc<+h84$8%9HtTJwyfT9LuLx*oNk;#-E8s?4`tG6s1VBTfdVHCd6Cd&>%PZl ztLoR}M+c-P2s;czU-{mcUQy}RIHQfR!&c)Kr^wD!dzxMex(8D|lTf^!j7c2udD1sk z0B=7?axOmTTlD!x_iN=U|H!@j180JvEdF4+nA`mL&fXs|!G(*TJ#{~PMH!$8gGmuF zPA=aAJDrQ)54gX0?NgIrZRzLkm#M`I)gbQDyt4L#2%7Z@R4ns)v+e>04B5h$({m+R zB6yneBN|mMy3vIDF7oWk;b*nAV}dn;D)r|zJT#O1a$SAG2~x`)sG>@6cWa9Y&Wwi& zq0IssFliCEtqY!#_>;LS=`#wg~Jmy>_?exR|S0-ocSU zO{Orznwhp?38oU>5?0%>0+x?QN0EnDUp`%1m6Ug%lS%DR?Rc1GBeINC_R^WydzewF zA4YV8GDHih(!Dj%tpSqq5}zVm81DDy*R61n$0Rv#$A*Tdy_L9NDMuG{YL9>MAK zrL?*a9enUA#5RQ=A{7+xPi1MR>86d|}1;V`JET=#Q8$!Hn?`Dm(%9T3joXe65399t{q=j~2bt_1N8oh~=dXtG| zY^C&&`f=?Z0#mw|BPJxr-COPq&wnI%xZN+*(i^c4F?k*G_~JpywGr;3!V8b0pr9q+ zsW75R>RP%tr7(;EHDrz#x$r10a8dv&IXXTXKqb@=nyB~oe+so!e4%vqX?!r|B85ZA zUm5wbQu3$U#*tP?y~KP%WIjNhB4%>ZI338ViMa2A3Wvz2zTSJ7n)|6N#Z^Z~{Zq-+ zmhFLCU9={xQVcYo1kFaxIWL)l6Q0b>#s?{gxzZ-4$`W-DMuqz!_KFkmh6>iT(9ruw zMm|?R%Wfr&mDTyFHa@gdR88Ux^R27oofdAv5LT(+0fE@d$YmlX9wN#xuclcbrW9f$ zA&`EV3G@2?doqoA-&~*7nWQ=G^r)*-am7d8-eMrF3GTuCuo>7I%u)^|l?dyC37m6k z(CxrTq2G+FJ%5U~Lyq?wRaML(K~6@w-@$7uk_Bkd__C6Bdo4tQL zZfbetF>A9PJqZ22*_4K-?_p>>ukCMEgtHWT8Mc!{vo%+x%_PDD-?_20@9IC5n*O+4 zA>p)zKAR-L^-$pvhJ18l2s~0wwV;Jf2~5b|&tU`n`1WPV1(q>I??XFw_@n1S_E+~y zPWi{3V)<@tb^Ry+StZIisdRXtph~p)^zHbMNx@ z#t%|)NiGHwZTgbO-ilp*ySbsc(Og}~eqpn9Up9}4&hZU9S~=#A-7RCF|RdCGj`F!$QCb~ zh3!pSK}u_@NYKqgUD1)22@kkmt-MXw%f5gf4!u!SdfewVSG;o3C+K7$tg7;1)RgTq zO7r{~THIszK*CbNx%KOjCNf3$7Tsb!R3CZpDdtyBX1IDvO&N%{7hZp&o6nuuJ~4ur zl3cPT4-%c1Ea^I|k1X9jh>jZ)(OS$$vC4~j5MZ3E*BKGxX&0CZ*Y*+=tI{0N%E~vf z$#02Llv#$J%Os4jHVY7gWvP|S+h{4qv8sq2G@A5@}|31lG;WZT(qF;GQ#^&9uCZF!~qt?b%FxR+dYqTexYXa}}Rcd=s%%Zsun^QNE-s1?dnay=tvUc4hAeRQi( zF5?&VDsRZ>nQ_&2L8-N{^!Ds9ofhxc_{rONIkX1r9Yzo(Nk2rB|Dny$zKwig<*?n| zc9Z=K5^>_X>*>SgZ#<1_vXPZ`N(wL1+fb#~)^cL#fhP@+StgNz$;n-y(} zqR{E)ACEdfI91CaVB#AE;7_gV63#0ZPn~Q`i1xmex!W4Cq9L*y3Pwi}h^tUp^nO;i zrz#T*;T)lbR-!_E!-&koQ|-N@+D*Cn7=)I=X$vutw;?(^M(^+RxMQ_fTVs+l@iD0T z_CkFT;^=n@!fe17D;1FAF$djJQSL?lF?Mh1ec?lw9xvXkJdttNZo&2w`)1$zW+6tS z{0(z#Io68Eyi^ABaRfGr4G6Nh8HWeIGu@B(Ht#`J6aAAT3hnqRN(L8e>}95o)jtVCD(^ac>b}RX)W0s-SVU2#L!eot4#`4Gw z9)s?Kn4$-u^%EI>%=;`glmxBFf6|_F5*AzIAPpz%{-ABN3*p!BA)~^mX3&{elhg2M zVvuJDOmjy(Aq2(#*Vh66yuZt|GBZG|*WZf1|DOw=if(9Ob9XsJXu&7@B1e||SBx<3p zjo`ZqYVN>&0q7zd*eerlc3m_%OZkETGV>)H0QX*XJxi&S7t}qpJoS!Ccpj6CMnTdD z)7!qPchWd#Y%WSdH865^=9^{WTncp^pGPgLwLaW#JYFAFzR*@TfN1wI@?w0sAK88y1y$KQbcvH1K zVthNZ9)o}?xFb!d7y8UDmChF%)zGF$h^q}fseK0%W(1FRTlf0oGblk@9&b0{iaz&x zd$XH^^sDeOX=VfkJXah>HKD~%7UDU+jEm)Jy5qzrXvC19T2s0y9U*cq+pOL>cQ9*I z_1%j%-;9q-i)xnz9B6d5Bh#t8%xsnf^3uy@DYEX>croL43mOf&V4JUob8`v+rOd6g07GgfFvX z8Atmd(zH2;`*Pk#nm#QV?QPX5o;oV~RY@N){dtLp~1K# z6fSdMf%uWrI@x+}tYqB$v~_>)XVGcY%#@{IK{sFmUdZhuS_zqWlsst7Odj2w zvH!`32->!`9wNO^Ffuy0`7Qc`zof*nT+=J9mK2+NC$k=Le4hFYlV-KSYE9Y|QVa6Z z%^WKORwd95slgS}I2B91z`C#zx2rW7ubqUoUMmpzi~TPM_$JAwDnd^*N>ieU(DuMD zMY_c06vLv6Gp|p5RqDfeHDrU)ZI82&8p3A}yhBcO;R&-ulNJRoT8VpofB0CKC%G0! zs5BIaIVgr7X%hRICV34Q=U3eq6Zjs@gMQPjLbIn_YDMqQnh$lE!wP9Psz%Ed|H$^R z(oC9(J{f(uVk=?7boYg>8=ni-s;6L!d+7&I2L{lJaG0R_$3{KkvUKWN<&xT`O5HQ~ z#%H-EDYLIHDGumo6;^IJ{y4}eCa=L184k=F5Zz2M(0SNC!5Q*BT~tA=EMZ41!GH>vnXocZfT!6~;n@Uh zTM={pu3ZQ55$6S?dtNFGnUEY}QNcuEF_c^0q5jDa5t-uW21WAkHJ>4n2r;)x?1M$3 zm60m?dtKHPD{U2JIM(e!Z%zty3&WLUx6A{&l->Nw%Hh#;-}HNVnEyP@uy1>V^6_)FkxoAYW*Qm#=CKhS5*;5`iKWnP*pXkWT>G2OW zsxcmi>)w}|%{Y}AL^i`120We-J!*y2o*z1SKMp9J-(xlOET>ANQ*jwG^{n?^>!{X zQu@x;=hv)vZmsu*cWF)3I4`aja20D}crH<^tm7gU(Z=<$e={d}J`IH$8Q7h}v6-CB%NXU5N z?*;B_F2k8`FZeNiYwPQWghqY0*THf*h|{mUR-8_Ozo66g`dJXJ0^^f;WkQU#4S50v zhCfYHUBAob??|-jwH!HD;p=lP8nGoWd&I5rV-?8|`8s2_San$ZZ3P=>2O|DsXP+&} zewU+RRYkSzs{=A#?{)dXSibx$?>5ZisR|Se6FhNw-Kkz8ek%BE_rXg|7gjB6v!{+# zBTFTY<)?QyhCNA;B#PPAIq2OuoZgCu8iFT+RB;^-JOzU7ItB)f%N%6{hYakS5u4gn z8>`$nr&0Avw_7~D+pyS-n04Ku3DRnUnFkmGRcK2lE;&2a(2^@@_s8F?N8hQ>vmekF ze3D`7L~yb#34*l9mTfn-+z+f{Cli-k$@nRQ*LN!KmBG9BxuM;M2yq;}Qt$&N#yCr}o~#o9UM z?dJ5`pVNc_Nj<#iPP8VuU0$G3u;hN(Z6y5^#q!4|_x2nYnC!c2kJpq6JgVEJ-TAL7 z>b1^ZXFkXHOb{HX*%ZNgFquh^^FVD6UaH%T^(K(dm|MrA*4$`M(T<=E9d(HBv zl+`Ondkt^aES+m5*3#r>?Y53~&QSUKT}vmXyPwcegR z*Sf^g)y*VK=|?BpSdV?q{T3ztQX70G$oci!no$pEsqKe|zhvoAOgdupqeB|y?les# zF!+2ET=Yucg|7|@Nt}^REL4e{SL1Qo;w|RNL5)fUo$?9ITbQ?Ngop7ic0EgYk&!j> zXz972J37^dj`q9GJGsU;HXr9!t)r3}NnO+xntE6nO=5;6c(nCP7h!2IF{r#!Ded$K z%*}xcmzZ~Q+InS|`L}B9_^wX=t}7@DW*kcgW!~S2poBO`3qm{Bu}Mo2O+0*Cf=k;A zbR>^RsxHZVwz-zim7va_FZ_lL7=MlGoFF?ulOgI9P)Fb-=H1>GdBJgq2-x_gwCq;| zbW?;;`t+w>XtuHP=#ZMs?swDGzUGrnz`F4il|r^;1E~|l)yv>ndj-)isgKSP&bhgE z1u7I2XjEmhK^08Du zOkU{7(O1Gv-yPC1JdJjxbxp(`iMfXOlrhV*A=S3gFTLBBD%`7Z|Z+qL|(T2P*H)@!tOZD-M<`hc|3ZCxVq-XYIk)cOdLcs>m zO0EnG+Jj>GHAW0HHDocktl+CkUCeG*YZ>X_k_nB&kJ@jXdO6Cs$4%?p)A8Z*--8f9OlO9@c&Tv_&*mZe^BezJ4NsE1M?+a&%2R3-!kGVtpK11GSr$9u?z7 zUTrV%Y=Y#z$-6c`c+F$~3q3{tLq|IJHD2;`o{!O7nK;BuYt}-_b`=X#RuguRm)6KV z$!4yopb-Cpapf{(!Z9*eL~Tw`?xaswwIAsq{vx6Uk)Tl1wfMZ;H2^L5v3!PH*;Ed1 zIK5B1`3|H?KJ%P?`(QmhLc5~8%Dw!Ygp{g&rqTaH+%>w?YD7qyJhKQd4^%&!~H_G~UC*VjjhHD!2J2bx==Gr!t+C`4Qh6()yk+!RF@tNFnV{l8m^41Gx4foe(x!JA=G|125V6(jS z_w9GQAI>J&3)Nxs!Dh}k-)@k}e<@4RWZ~#xz=Jl!v4)`uDDUX%8C1Yb8-<8RP~h#* zA^>X(tPMPg>S`Cw=;O@%pVDiqj2?-CNi6MeyNz2ZxfGXnq7g@|*zaEPavM@u#eHOS z<_$cCutM6>5n!KXrox^4q@S-gBe<02vtS$pxdm%D4`g^h1+adCa9tQTbU{bOW*!xL zFLTyhaJG8$yu$*$($$IbUIAIb?1rARIrF+Fm!_1YC((VRTClnoc4;eV15pV!T^h3F zXfI357_YD>EB5phqhG!GpwALK6W4H_MI-_Fr+^CwuqX$sD-hAjpzp43B^nob=PniM zk6}@_A)_q{XLCgPli}f@><#Ig7=)`=oGP=d1RJ>6dgeqFU&yp-DQ&A0|8B{BuLVZ# z!kJ#fWs$Dh%%J?^C(}5syf2p`AZG>O4hL;n45)s!$E20e;7k?^sMEI2$#SZY8|wZx z5d&>4p9jWH402+H$CYOriBG(u3Y*KrRb=t{Sf?-o*V@X#A{R4kPFxk{F2UacZ}ZST zX4RB*_-F9v8~mPNJLQLi2K-B$wmDGCS z?y=kp1=^U7Q<0%e5JoI$n42-=!7?~h2Y`N-jX!U0X~5vmCOJSWy6=;%$GwQyqpIs4 zJRx@ZMSfMVdGX}tn?UC*p1IZ%XJ>@Tj`c&_KX`w&bm_h3YUqa95O_cF$@Mu8du?Om z$e!m5`-(MZvR_Z3$K)95%f3rn`9|z;?Cy-aBh#f~gscCg8)c0Y-46YIQ~uPFNHg(n z1w2E2+uYGCXTgC(O^=FhRWuhQ%v^xpd^X`CE`kPrtbu7ya)!(KMW zT)!X_I0hcaGcWU$Y(w=}-Hu~O)A7!HC)Lm4OwpC?g%H+|K6w?|1^ao~ zNiy}$`h=crE;iWgi9~tlO5oE!$8(Xs7Y!rzqnu;KFX9BO>;LJi6d$3PE+mHN<2X8i((mFqm+{y@Oi+z4%41^yn{@q(FtSOjB8S(&rX(mU`ITvUplM>0P)h%F z1`?NEb-AVSM}O*xdr0h)evOFbn4R4U7Q;kt*Ck=ePzJFo0^mLy5%s)*CRlB4CtEXH z6utFTI-dsBd=P(uDP6kJtv9{dB$aj5wzzc+sIOk%51qpNtKHr7GO2v*(lUy+%9gKM zhSH{oKHBeH?C!1bp}WwWP){o1zFe}S%wVS=5f@}xmPZ{#NieBt^3h?7$KFcKLpDh& z(b4)Avavk@$L^r%e~Ii;lDOEXmASFZI&+<>XamM|7t0l_N+H_J`8c#0uPb22V6FYL z|A_>H#LCaDz^q^QX#>CagnYFHk_~=kgTdYvhkrdfKibroE!7In>xdmYuJ24f6qVDu zwsLD>Z28JXB@akD3@Yq+>DjkS1b$qkKISHAAmTxtpGa#hZy*cPJ*dc|EFO9yg&rZq zBiQM(@kJ8mvVYwe70};tLu1;4l@FImp#W{VUIx(Wx_u~Ph0Ex2Hh0^LHXbKRz7C_@ z^P0Rc1H7^9?d$vpCD zQ@M`4vE^Gkr6(C>>o~Yp{GP3jz#Lx?j`8&MeoNo%qkR$qe~&`z0B`JJXDv9{kaZu)A7d@DWBr&%e8X)9fb|)yNDm{L2=%g|aaoHo7jw@d z)%8|A9CvS=;@A7@#$7z#=z-7Eizm`PXAu*fS={>jRP+98;yoK7 zs-U-K!|mnxf~hdXkq$PLkc|uJ?yH(mxyKE>+pD{*PX8etxCtvnP@u`=;B_UWSbmet z1vKdA2t^MI{ut^qM^M4vTWCHuHk<8q`?iL3 z1`}or#9pj#H;p2dFQ}heC_{dJ7=$crODyk7FcB62W#^o(Y3|tXUm{{XRIlGHuVWTj zh4r+$Y4_#3urss;@oC?2kFCMb88GTAg(&03Q9#rzQu(E_7-~F874 zQ_LKRjEntIf4o2aYr1#Q1_iR?d zWDjl?_EO8dS2RMc#`ryZ*pnY35#6{;jP%QSKM(HL*s^G^fNxrk^IO?Qa9z=2$_iUQ zi7%g(9_{q7e*uPvD8dgAd5A1vemf1MB>hXo`fa905IdmA;lHS;xweFGVzV|LBG{*| zu0~i*yq1elOztTxz>8dqh0G&pRBnUIw^YMd`)O@-pY9B0qO)4l{)kM$Tt$3M&mM}} zKhOLo#rs8h)mqDhdc7~uP8MI<9Q!iDKY1Ts*w$B6Cg$r1Q8{Ye@ z)<6CL$_Cv=yeUjjp#|2D7-a{n%C`%yY1WPDHv1^)L zYbAC>PXxP-e#=K99Fm;+5e>lRdo+dikk?t-ZO=1NedpG8bR-aSZIpW=d%hiB8du^Y zey`7eq?MIp&O3f3BIC#}7jcZhkiEbq6@kscc^cXMe>d_fK%srlW!=2$HN~Q`uwN+i zIvY>-_HN$rdubFrEjPtoVMNsCeQWt`uyv6R0Z%tPZfD0RT3Lz zPa?UWi&NbyJo3V}kE8FzZiA2%hO?cTZYAb!i>8a0#++Iw8=U&J`kg-3vZbx<;Kheg zP3`=tD7CkfkVC8lfqds0goAGl#}MxB7x2xnznaBMmb<)`SS^FaD6J~RWNE)|p&t)m zm&oF!65taeIhqo^db?&ldlb@TjSs>xJ5{*m>Tf2=u+%l{{LD6r{=@E<{^Lmrozkna zmqV5Ok0gPMx$d8-)fK+P0bhKU7-NX;4D49(w7-%BE>_j=$C34n<-@Lylc{8ser+54 z?fVb2h{yO3Kokator+W8z#XjWw9VGy4eIdP8AJZ^bb5jaB%oI)2qgd5-FYK5q{Z2z znMQAzNd7a$A7gOTg`Q-%P{D;`6h#0axHY!6uB}4n+y-)GwwsWie%qVWns1-Zt!VrFEp6<(lq8k7*OuXurt#38 z?ERXQ0^^Lt5O-A4wnaA^G~PE7C=X1`?mzp>-BR*axo`3gfTDPy(IMy!FUY*g#ugID zvD;!Hp(JbIdz^|^R3d#+U@P-k-ud0>F`ZTZSVCEiw+>%VZ>gtZDN|-4~2S4k3NHrE)>v8r<^Fl6l{+i;u4!_&JlIA3d-z6L=aO>G9zz431Bzxzn(5989oo*a64Nvxrs(Nd$HiO z2eNacRG2V}O~SDd`EUE}{u$m%F7VgRiV+~$$r-tsM(MZ#!)WaXi5grY)9wg6)kJ~{ z?nFff;?j&6UV$oGxj@%l46XG;=~pdXXv&AeCSB-9A7qSYWSVT%^Mp0~Xt!RKF5i#< z)O8BZAOf8c`i9}!_^9mqC=^Kxw9y^NcXK+st~(pJrx5J^=U+cqNL*_Zrs!}l!50Qx zIA3S2pDR?)53>5E*P_>dUTru|NqZ^Ddk#N=PMtCl2142X7~I3Z!Kr^wp)O0pa{n_A z-R7QWH*L^b}9^qh+IE+0H< zLi^qZ3r?0`t%5Th%{)YlwMP6$J!eueVWnqxsLd}KK6h}}8*GE_42x$FA6%&a!2^Tv z!~9!a1CGW&DG8T!5&seig&1{|%l-t>AzV_TxkzzN!UMI^7IU&A_VBjWIaJI15&9b3 z_$DJxFxUQ5X9l79^hz@F$E`C7q{M|kt_vG<;f~pihA7mnSV3N5N|2`Ib~TUPtfZ?f zDw5I9>W3!M#@Q!sKYHV76h;cs;KtL#(RZS^3c2x0K$j%01}c;Dn{)=xO!Ye*J$hQO z5&X)cC%Us(ba8uJGBB!`b9w)TWQwVRg0J=}Hv^Dc;l2$aFTqX!VvDYW*MONWUp3GB z{yODNeg5}W+P|E9| z7^!;`y=^$rsLL)@X~L7L!^4q_$KochS%77Bw*mV>3-eQjgD`+gsc>d1?V6lF*Y+dc z_c71eN*9Esu_>4$wI~I4#$s&sB<2x!2*j>H-xY9){=vn{FB@xMn~}=7ex-F=nA+&{ z)fa*(@4laSXD&}>9!3sQX(2&~1|K*vC95U~~^w3Er z{zYc8op9E~U7oOk2r398YHGP0oezxxN;^}wEtvUS?#OOF`S_wXi_$>o?-l!bhles$ zu5?0)>(48`Yd<4~9Kr&w43bs1@}R z^>jPi47E(1@#R`tk611t^(W#k{;F?ag}}$Mzne8@Gy7m2k=KXQ_OD3K4uxmY#iw6$>%K2WMQwD_u;}!s&0ucGxT8?2Zy(* zvIKAt9b+M()Q}ITP{s`xk!o;c4;LqM z`#)7=Erl<7%6h3@D+qjgB@An!RORWEqm~rR^9G zsdbo=x7bmDu)D$Sz`Rlmn!ARy!{NF3uK@M~xD;fpfCUGt{zcq>?#AX7c?uB|Px31R z*{rN@=u-iS{)rVU74hA)+aWkDr=+-%e!3qAh4qNzP^`pOd4w{%N0kfGKidmcNTqqf zK3?fAP~TSnPBk3Vthqujpf@j)63Hir%7h2=n*}YHohD0!@udp$n zywPM?&de`U48u<;TXv!8;}iyv1V;Oze;?7iRFHqjo=pYXNU{ zZ@m21Wo~K4`c${pr{~XDODy1usbxa$1u7UGNRihyEe^eS(r*gS)=K_MlgMnVT7a@t z7ulEY>NO9D1H}AH^=FW7YVI;fHH!I20+4C>+i`TtAu_sz111@;OAWD!)pV)1Q!13O+9AtCV%6TH|i35cd;1J z?DkKL0zOttT{7pTJN4DQKppkhs39c&CnofW?AqXvEjAHA$|HA^LIcn=w+=(@$D_nc za;Q#mjJGA#1?bE$yQ-vj@s-ePUd z+6wk3tCI0Av(O^LMc{Uvz%uE42T|P}G%!pm07tzL9B_;=e20D2+Z`ZwXDMed?+e*^ zJ7OTNBncm6oKC|++>^I=_N#p zzxc8sR~2yu4aCs_=i)YVk3?eoaM+t!cPK=D8^M6f8-#z1hJR%+fcZA*>5xm7ggWQG z-YF*Se(w1Cy|=hzOQNeml?noIW(rQJr>Z8xh?Fzn8)BV;5&E;^IF3DUame zoTf{jMNToMs16r~w;*FGOV)5x&yr6yk}Y5?Rz`4oi(!hmlEC?HyMNL$Sz2$IhXwMO z^&kLc_s9+#i-r!+aIb@TeJPGb(4INP`%BF26O9Rzl>5m$$XS^P%`_VwKaiA^@Kp+N zfi$}OD8m~wyrn&`$&4$z)^3^iqu~amSvxO)-#3V7mg76yunKyr`zCBnS&VP@pCtR| z!XY}8&PK_(pT=xbW&pyx*UA_T6#xuSO~K3Msv?=@jwh>-30}>Lfz`};yY3ryN_~5R zfkTfL5!V`cB1{QWw#ozSRBZDy^th-C7F7ER$(W1Ws*g7xACcGQHNCt2X!(io9RzPT z9pvFnRksqDeE>nPOzpc#(~p+mus--;)#vF8K0S&lr0O(d3Xo@#Uejj&N+ButYv~?` zgLLFRhzhaw^7riBJNBY@| zROhZ5Nw-ez^25=ilo_Q$q&6x!5>0d8B}8=r*deIQ!Hx$*(+8GWrA|~`1KEq{o%@a+ z*!tJ+8>^U!eLQX5id36vdfuW%RLKh2e{my`iAMS^4mYJ<7dhyBk~C%StGsplXRP-k zSYK%~US(7fdJybl-xg)rZ0pum((u)Dnrwu9)%Gq3K1J#F^Wm>I19W1bBs7Yyt_GRE8W8Wlenb7fqjey zgN%ypUQS?=6&V-G2@Bm?EUG#{QpG0tTAViDEh#jHCll^ujXemt{t-U@yb`b3L);Y- zY#B1d&02dR22o|h`ETmZc8d&dkGoaW2{TK(0A>3Cc)CPml!YCA)euQd(vKHJ@`1uJ zKwhtaoAbDtQ@)4ob2oc)BPKZ(eJpLTa9s9v<4_8h%=$KJQ+Q?ga|5~jc!<`@KSF6*N?Bw{}zQ$>u$vwI@z#0hS{X3Vg{Xx;c~y{4r)g;OT&87`C>4C_hxRm!l4ub>Eg+e{NKG=e{m@yhxZ#)FUW* zXZc2FK{;S6iN>&fR<_o0=*P*}AWSdLsWn-Fx8a#d9j8UO`9BeqQ6wZ>Zt;Z|Q8+R; zK;U*g9OmLqG3o~Mx4=AJEgML$^XcCE&MGgNDWI)(Yptflo({wlG7kVgwTDyUKuoez z+z@U;e{19*h~`w8%0IVj{-V~|(=iYjSLM#Hirq4o{W+HvhBU!Ddw7Onw9QgqC^zoq z+Am>itPIz^*jJrS*_ZtNSr?KvWEn@-^Ga4a@0Qu$i*&pdASq^d9oi9(yQV+9Sj91; zx;$y9@!AXSczM4-=)p%S#Hz&67(*F3#hT8j(%p9-xOxOvc``FuZ}D|q_Jf#07y)}J zH#QQ&iS`gNU6e`h`#bdGg7w5BUT%nfAlX(~ek|Zt?7gY=NMjd#xEa)4!~gW=VTbW-*l3O!RL1i(aYf)1%hAQ=A~zrgSR z6%LmWE4vmCcdFE@D)|_7dE2RAeXj|gzQ{y*UE4oWrX|*MJEqvy+Feuf#fUP-)T1sBbE*|Cdf&)&<7}0Xng5 z#!J6stnXoKT~bH4e@%ptN7V5Xs>H3oY=dyzAx7&IG~X%Wwk<|&W2~jSGcP)41ea&} z`31UZ2pWW66s12HN&T#|bM^`_1bqMA>wzL`B_ zXfO<-zvCK6c!-yTVXGjrZCI{s?zo?Z`=zo!pZ)oq)DuS$7-jeMcz+U-kCDDG!3y_z zC2TNYk7D)Who1v6Xq3pv(Pd5gfuyyz^jPtjiF5Me)kJ!(S< zbD&->CAb#*PYXG*j)kEPWP;bxlt@nMpYZ9KO2Q1HX)&R6#VvO#MOn$kp|ZKs$y=_{ zgTsu9*!{ECF^`!fd<>AZzpLhiqHc zG_T{crpK=XQr1;g%y4NwB7p8s3rOWE1R*yBHBd|Z7?e+K0~%tJk7_=aJ21=a{3P>$ zH~HrXLEYB^P`8dKt%&N4XEtPS;<^=bV88wNNMebMD(B(~5~u z*z%f&Z_3YqiAvPAZr_f|*nLOAqpG!s`-72N8psZzY6rw}u7P3GG4+0OEdu&5HGN`)+rw~rL z|DO}dV*{|6X!mn5b3f^9LY-^|{eJ3vh|U;uTplKi=|v;>Pk>XuaFZKvf!V$6Qyd6k zoUS{9kkLfcfL;~&>py$m4$rTvTVCboStT0_xA&4<&WHqAtwU6BX&Cv7umu$!h&bSw z5i+p1fr0KX|0=S&{K79QpA*&Do@2x$W0Ls&Spe;X$t$UE)weG6FO!uS%Rn3ZmRSuB zUVdekq0Y7%VgoLMUFDP4SNH25GLLL35g{J#MOq&h4tYiXO^G{J<}AlSwF=GVdGzwE zSWdsW<)AW&OVS3ogNk`6YraL4^T*@QZrZvz3gZj80iwboY7&1D!jIMeiWL5owLvbm zL06#uw7>KErO{E4f3mFbhvuIFm8Yuj3gc-ZuM5VXC#Zq$S%c5|heoSM1tQI1F_V1% z5~;=Wl4a4o46)YVBh}Gm_wm*YyWyPc=Eo~9sy3-M${s5oUb~#|&EfMZ3Xi?qI;PD1 z8_p@MtR~3Q^ImyJ8i6Cx0sUU&;8+7pN_?kAnM-a<-B^~KS%9~Ox9^YDe>BPViz~$XgIzn z_g+Vt^4h-`ql(^(MYwtdZOccBHFG-YVLb{m-DKK3XG>3#ea}$2Gfd>B|2VuA&azMN z?awkgHzex@3Z~7%JrZ>0u9omvyf^Cl(1w*s@2d8Xl8YToOG)G9I4@lUn6#c8-5&b? z>;?Ld3BCb>dByvlGEZ(Ff6y#^y@cn0C~!bSMH^t#-4TZqbi;3NTdig$^*xW@A?Nhb zxsk@b#VGEfriQ1uATQ?7_02O7gSSPN7D(j7WSvbtz0av5;f(j`9+4m?`%<56+56w# zO91XFqlrYSMkqU=L8Q1y9jr>}Ru}M~OgmrqpHP=ezsC*e+_Gpv{oi$iXjU%_?&ie>kh7C#q_*}5mxcfw`1;{v6EqF& zArd|?MeD-sbD+YEm5&{q2=H-Fw{h_%F0Hb7mNi|*JdvpTaE;=&ZrvtO@>g}{-?q}% zn%&dKL@8#a-N{DlO-h><+<2u^$t)KSJ3UQ&#{OklINO`E&m-ym$j?-pRPGWkYFs&H z7|pq`lO3k4U3%E$a@=_EROL)0D?EiIRcpc!19mt2jCTi$ql^$v3?g292wLXa&5s$% zQz;gX-Ja)7zFB0!Pp~x3@`yyX7WF6$iR^(^j4!Nla7;g1E_$0LZn1!C_8SHoY25c% zJX*AIv{GvPe$2u4LK_5ana37xv;m2CwwUw(Bfr%vK zBtEQilFxeN$dNizmbi1Y*HH%6&ksQhxPcBENkyCn{g%`z950k(0)59v1zUTsWo8C! z?~qe&SSKc`ptl~MorV|IlMS4b1M)*(wKEL^DoHB44Q-zkpQh#AN2wnabTqg>!2kZh?R4(xlyF%g9?XPBgp+|^o28bF? z80$YZ5c1gB&+X~GJ@X8Mg;y}2b7jlwCI~VRW}aor4%xldc=(1@onJNwdwD^E%f@nV zXLVtfdbs$SXMgV(!?AZ#Ttr49HU}?a?ryjF>a0LwV~9BWS>-z*v6ZI82UCDi-lE+L zjs9ELz#aF8!bN7CMz`>FTUSeW^XIFJ%R4Jai!@48^6b4V%M1Y{=BkV@K&zlF{qjLS z3{xpujBQD)ZJK9EO!mr8&$qEn+Qz{3O;Q4hlU7)|$&>;MsoVD9CQg_+=_e+Nz}URt zyC|4aHps<`5uP@ic2spjOzFqkOCqItGSLVFkDJ_kZ*+ zs>92+Vxntd&9iI$E)}CsS8J;Ikwbm-8Cn*Z@-b_->u=@!B3o8vCOn0R;24Tr2m-jg z>ec<0+|oa==#KG6JOOQK#vwMJ1HEI;1tBPY(v;hsOQ^l$NQ~F8t>O}d^h52wqQ^o^ z^_{%ZPks+54h}zfkPi5)@;D=#0JFEHMH~O%=Nbe@|b04k&WL)Cj$4~axYNkDJ zC~oQF8m<{3&#XZDT^Y|J`pLAWwb_q=dv%c((Y`ok@)v4=)WRHqz0F8 z;jk^2zHFW4h)qkmJCFRMsv&OaiPc?FKSAl%J7gU3zqx5~{e8A{nBU!ESlddMG8e;& zKnc%19gi6+7BT+RFpflex3f*O6L2rA6<|q0WajY9)cFrEQ!%?30=%rhV!U{DO*h~^ za1Xh(hKr<-R#Mc4z1ld}OfTba&=6>)V~9%x7|qXny6>dCBFy4~E1YxFU69cOjpjB< zkN6p^bX7mkGV*@XW#iL(lx36=ZBI7+H)R+ao~s&r1hJ?F&pm_9!ZiJxI`fR+dO^`~ zVY?40qTiQTzknkR4Y@_kCKZr2$yYA=;JuwAls71z0O@GLl_g;9g^({@t{d zEM)~jb#%85P8)NHjzVza#V}^5{KcFqjVPq&^+UlBX%cW$`-$LZ^cJ$iR zqp&pP?svSZzPEpj&>-{q0V#wOO~rOPU`dm#tQuUttVhW#Z~8aCxgJP5tS;>k{PvF>5b~&qS6{3WU}R5DAc|N7*>{glnlefKY9vfSXmxX4s-1hoeYtw z=4=3CMnouK<}YlhC={z?JOkx^4MY$fJYT!*dog(zgMz>RtiPtbTgk^n+s7Djo3=#( z`t1*Nd39I}TX&A8j`B5`alrc8@+S8d=!A#+I?nyn`X{O)ARo>_e~*6PWgx>oiS5AqOP{DNKYo1TatX+ZUFOE;m3q<1slv^{b=|Ci{+O{%Ip4HZ}=lnf_f zI@g?ZTkOSn5Nqj9eRQFv|w6~)$VzZ%q2o%|( zddJfnb!>UviR1YFA%&E3+4>5kaVv{eBqL&kW|o@`ua05v_YiOcu=SIwY7I_w z6!|Z9mCO_1nwuhzeqOLn+HK&0bb6WVN5_OpaJ4qPb8(Sr?pylb`&q}HR`x=S;*=3u zq=w&=Qiz4RLvPAM?m?boFH<0-SS!?ESz66HSX^I6uf#3AlL>BgU?^(UUt)~bc@fc; zLTVACJ_Iqlcy|-isf%$!OGH6H+m+4vjx*_8(_3SjA?=3Y$;aYk*&U<1h3nUp*;N? znq49?1(CVjfN;ViyaX;++@Rl!-X(1`SR-JY5)KTXAc{J{z#z- z8Qf&?{g){5BLrT!{21q@hYPO&ANw7;IIta$ZHNxKJ0$inu$PdFT;af(YKB@OzqnUA zEfRR7wnRfDeMCwAL@=fvY-5rl3wiQz4;dEFcrVasG?vF zKJT$qjfF@AybXOTsv_MqFTS<7I7Cd>8ewH#yT~5NL&GLIr)+CRa{Ij^&1&Ao$D3~e zC6~fRULB`hwTuKpJO}=k(Or|{<{f(AiUu7=Jw13jqaj+)?+l*a_Ks{^F2T7P_Tfm( z7`@q7OEX~U75N9s;3D_2rJ1q$`r+x@%`8sCf7D!$$zpWUiARKk0 z@lQ}CdcHZZx$CLBWBTw7<3Png;LIH`c}CW%egkmlyz>_TB}d!?x1@>4Fv3|?xiGh+ z_6NLo|1(e@fhMQ=;r_YzA$?7noG_RFh5PM?XTz;+fKe$vLlA%{VQDVRF76=8L7|?5 zGJm~RPQGU!r&%4-ce0ybRkJ#5jHb4+4rzL`r5uY~E9^5}EPaHh;N{&Ie;OHhp1ZbG zG!81fWiOH<8rxyvWuF zP~VdKEK|_?Q976Jyq}rJoSeqm6!_O5vq!;~r6EhIO?8!6n!!*?g9MpX8?)ZLS7mTB z!@f8<&(vz^q&}Jsg?$EmZKUnw))Xh0AJ`4K<3qR(L{Qhw-a z+~%MfQ5OheJ}Py(HU|Ey#&{Oo0_De+G_Nv)YN1vEx7cL8ye3Xqg-K9FbNEHsD2_&YNwA-7q4a0@Q-)W{zq-9eU(Pe%~ zeOyDn6@Lz5Ap34vKiX5N4H>3@5 z-%I5FLJ%hO+X`TRgkxi@B#Ztf@&xaJ=3v1>=zZ4tRTuPR_b9ke4E+#5#f`K2-MaMg zfsLtOb3lUTm0yI2uW6!=g)Lffk;S-%-xOA(fN{aoG$$(1_&$TeaOlA9VY#|%b?yp3k~MYps3AuK?AfC5%r%+RN;Sn zfE&u9Ghk~IXk@pmrM*^2+D!{km}qZuJB={s zL%BDl!|^bhW8Na`H62-AJH`QCF}sddH)pEtK_N?BF3MIVoi}&1S$@AM+4yxyC4G^6 zQvj>I6MFv_K^b$rk>jE4-(;&%Wu;5v)@`#hv0zn&?~MKZ`)OGNGMpPzE=+#fUj6lFQ$o1Pv_a ziWiAaTNpT1yDTo+kL-I1XMdnfmHE{2ka_pV5!N8<>ENV@?JyESs_Klmi?_nD6>`f8 z!>478?>(1CW-9IlM} z%*>Mkfs}kmkunjAF`L+|#>O;uIpS2cA0peT_XwjPT944J!uF-3N;E~6_~w9RZCM-J zr2TA5AqO&ZeQ@Ft#q-9yOOu*j>*=jesKN`m0W@A3;I!*>V?jv(iLZbo&uG!3Q-Q0{ zrOa)q#n{52D7dtHj`LT&9S3UHG%oPfm$8Oz(Kfq)imUt<)#sq?)1Hb9?Q{dSUyr)^ zhA)g1Gh3NgJR$*POXtn$i6WNnopsx-U4)5mG`0)K#`ws*0PJ{7I*^{x^IRGz>(>KAHvW{SHbw@H^$_F7F-U;KS}`reci%{la5(9p0@ zA~JUW^XH)C(}oNAIN<*k(anGxF9XI%?l{q!PQ7X*Y@w@piB3CXSM$C%ZhUViV8*^u zKhqscd$7!&In|0cyLJj0?`FW1!jpEfKR$()*|_>6U#yuQFfGy54vv3^Of-6!d;(2; z&N$Pe;35q&g<^$K8{u2a1inKgA>RRY^)A_W{zUwH^5pj~#O$APq8zMgP2g`LBtfYJ zdSG`8ASKv!g#jXLG_Dmr+8=UZ0`!j>oC2&sodBaXG`S9`!GSty&c=|}(i6v62Eze%0%Z3Nsajwza=Q$-Z383k_l zaOsp;;X`qB0nl~aD}bay*Lx9GEx}Z_*+b~(W9ur-rqoDdE5F!;p znGJRUtl;PnD!fqV%qa@zREqm?7xKK_PlO^kqwdk_D7^L98S~VP{kashL_4(2Fejxg9@I zcoC2Dh7efVFkHoU=wPLR_L|%m0D&^8BvnJyP*=$zv47$b|LzlbE7_Bty>pSC|JvM0 z>TQ$OMZzOjHrZ=eE6(xrpY= zqs6}@1QAeN2&sL!S3;`SYP}Q!B{+VWf7y zIo_;v?I8E!>))&bzAm_=wGeLh!K}su)2yxWFZa1ONPVc8y2)lkftJatYJVY3DMmY5 zc2Y@yM(j@ztIRROwXI%4g1#bh16=R`7AVuNDEwtc#^@$Lhu2j7fvAQTo}&GRrNwKG;CrFXuW#d#IGa<ur>~WSuYWhYnH%| zp)TL1qF=Si-El9TD+QdbmbUk$?`X5B?Rlr8R$F5@d_>L=CO{Wg)rIT!99{&4>wH+Z zwuzUI?Xir?tvRpSpVJh8UUbMY{jk^A-Ln(**yWRZ|M=-^uVwbZMZ#Tda=2Sy>82|Z z0aS^q_Sx)dVpq*{n14 z)7L9#xRy6tbDhAWczfPk?{3*8!!TOe*JSGeY7*e=h$;J3S*{IjQiOOX0w3Xpo|q5)X(kz0I5t_6wM%A+l~2`z_i2 zY{7fWP)nEXc)dgA613nWd#gaEJI?czNvM@u*MjoLRG2%P{fh-+t-$cHJqyL7JU$}x z>)~HkxAb;K?3Xtz_(RB7)4rP8BbvGUTk*zjrFBK`kYYcgRk~$+D=cr~tkh-RXAt0l z&+N%2DR!u%FFDM53W@$DdIOCo+`%QF4A}55+h$-C9^3;PLQ8eupf48r5d;n&PaWNuQ^$ zgmkxIPD$^grC50R988eLVp?G#NjAVH*OU~KVuxlwjpJgEHJC?gHnnA#z|1|_=t&}k zr96D1!g>K!R(2Oiw6v&@;;c-uDN)Tgrc1A}WRYUuTifQMk87KL*i%~YrK6pvn|XEf z1Ofwz&eWiB_<(DUkTqKc9Ec`NHk5HcpyiS&x2srP_FO}m;^X*5X!Azd*I7_hoYYvi z2^{#A5^ULp0Y~&*h<7VyD!G#vwS?K}17G&F-^q|YUYNk@I|Ub8eX;&tTT|d}+(Pd2 ztHw zpYUqR!YC-quaC)95dqxAJ7XhA7;8>gL6f0oL|S{)Zyu zVFA@V#5g!Om`%Ch?c(>&eG3&7f;El3!>dFgomwygQFw#a}G|M*_H>FgGePV?;|! z_X3+{BRtDQ*VB?wg69)CA$2XLg0V57hhG#gxs98LM=vUyzEoPh+{A|c{=iW*k zNE>iue{`%Qy>26adwX?tgwOlFPC5(x)|3!JEkp(K2-k()bN-7h*k;&UB2v%dCNY}-TwYTJy%B+VH!cyEW#qI?*$|Tn_Akn(^<>s zkBgI^$7@hDHt7(Per8#Y4BM*Qi$7Q8BrGGyLRi)hrNFy?Da52-*s%0}ln}GG>aUfK zn=q;wQmd%2cl0x~qdaUg%)OG{LL4z-X?hotmiXrx>hre4y&=4qEAxpazRiQbU$fIj zx$|zLWn-QtuRRf{Fg4DdOt>J&wRvHh2Dq569b>(#Y@I`HH8z|(eCfSFke`3pl}~H4 z%R3nws~KQuGb>f%QPpYQOxh&<1En*^X=r0Z5(27SQ^giCKPv)-@HMsl-I_G5I-8l| ztNsT(P#$!HI6(==u7O3wDf4fObm-rsx+Q~NT3T9c(3Htd{X7)@vfJL{`a9W|N<@BM zm{9kdSyiXaWdFkEIrsf0GiZ3HE>HMLp-VKkU%k?i`*}93Ifr{j&>x?joJ%oe!06OXqCDX zR7-T7ppGlXj1Sr}v|&%9@!F*amW*FA>txxjM#`Gw)Z}$+?cXId1iIHF6`nxTYE-wr zhc*qttHHp>p(||$V(({CXw=aav*6n@$4~Fkt}XmFkB7%mBZ7t}{=zG)kQBxp&5WQO zsuRtf8ti`9zIewkV< z(v8jjFZSLutjTR{7exh85s==AQUpZ6LQz1XB25HDr8f~Np$Z5D4Masix`2R!5@{ke zbfg9dML|G{lu$xKQFzmHA&-~6=YhTy?&is+fABHz$Jntw^xu5%H z6LNm@@SH?`;`Yl5_Lk=^%{Z#qHWc*N8vq};BlJvDf?m^rrj2v%UT^MTa|UkNsL}?u zv-A46#HHC_|0BoNazT}DY42Y^=J^f&HO$;77B>p|Wdk>e^tl?$m_OYAGMSzhpJDqZ z^=e5=O%a!>Y3IT5+S_*}ks54V*DYlD=EYCbGfSb)3HLCZjdsOT)I0cgac;74R)Jl} ztG+MmmxfW7J+OPPpYc#@Yl)rBEV4C(wS95sg@4DEbZX_%feGn{TMxOW zl!uN~`96AvO$!Kcwsj8Mc}fB!f>79&V~jWmfW|@v5&aKyWh8oL9cz^E`o;R-+mR2v z%(tu#r9_Ucx!iTy`-3Ur>OAC`(9_vn(_ekY1c=7@qzNKxWNzI6#Fl(1l*5p%E7%~0 z!9_iqQ-_y%Y^Pn_7@?3=yHm|eY6dWb*l>c9kWNj;Yj@0n>K7;5ZjF0bY)P3Ex(E7} zyszObe3&VIA+7m#Bych#MV)dyhc?qF& zmc#sjwQ-lsPK<`8*ESE$_pXtlDd{B4l$zwg56`e44EPDj!<$6frm9^?-R0!VKJ59L z)K z*Y&*D|IlMUgCi%bc5LFY$O*|A!1OPI*{6gRc~foU!>h8T{9tY5w5N63$wOAFI7h8d zyN*ce9nufPN^GUr%i}_t z93C4d+aP6}onx9pGY%2WhnhZAZ9{fj!Yd8E3{Bp=SSxiRvw$G#R8&dMwWPzob(e~d z)$PAy0WCtdLYuYV%PrQ;QKel3ubp2JV!811ePZgt(<9%uwHR!5-fITcy63Nml^-D3s-=Pf0$4Ti773~y8)y?7(JwCngu7SF&_D!9>(P#&rn z*@A#v-7)JEh2dD;gshkd*~9$~SEm}hOv0NC0ezRn6v;@}7pW%FLA=hazP3!E!v(+B zpZ@B<|NHAyKUo|8cYOFZkS*)q2Aqvc!oY`) z+Wf!xB>vSSL;e`}UqmDw3>AbX6@8a%*aje2T3psJ^%6>Wo`2jf>ACR`a0m6(wP2jmZ?_h0W8qN=m>l1v8`G`i*RnIjWn9=g68(Mjm+$IP(5sa{n9d74fRfOd zA505(5(-VegRJ{~><^|S&Qk5~G9VT7=?BwWl#ZzbpgD49Oh7je!6kn%?b`;z*{-h{ zAL%v7&*w>c48Ctam}vd~^y}xozC}ub9y41oPM*(&0P*(6sY7s>ntu8o`#nFQU_XV# zpDk$>Ko=qztegyetvb#*6oU=*gGu7APF?S#3=Lq{T0s2tj&<}9Eg7WZ{C_abnPk64 zzd%-l=AEqrja&dL5c2cKP7Wh~na)=352kboRTTRD;MN>82}xB%(xNua_%_hLTI!eC zTtjVW1FDh8A52mZ+sH2_fFvD|2qtPpXEz7@Vy9o<>hm4t-nK=Z0F%V>; z``V7jrmek9_dZ@(Y2=V@5|A@c5?@?#g1&--U9_+;((vo>{A!(F4?5E*=HRMxDg<3< zvr2U665nPxB7tB6S`CqVXNGC=Gbm1~hy7rw$_oec+J@#)#j534_isaZ!D+$GhP>UX z&tE#qP4bHFC%)kyIipthwF5XWG-*inC;FagPH?Xkf@|@~ZDgA%plAFL2mD~#5j66< zo}N4#O5fB$4SeH||MTl#`<2yghX4KC+ke~Px7GBw9sah%Kc6oD*7bnElQb9?gE~#N zMHP^ntvMi{N2S_WSO4I>j38YQ<(ojjE{c_NUMars1(TPr}7Xxf5x`)oa z+h=@AB@2MleXz)wOre-g)ILq^S5%blvuBc+L2qJHO`v_2bNGwBVlA2$b3ruzQf#L+ zD*OkND!2WT_|{orB-*iE3^wASl|O$`6SBCeMSS7$Ho_J`^{4A<`KV zi9@x6ZZp0`%zlv9I!E)OBJ-vuXeV8blyrs;C$TGp*G?$RT9wM2|1#NF(<+_peYx?Z1wUlfZdwZ{g!%bdVO1?ch3!SakI^L=X(G& zc&c;|lcI$4X~zpgohKY{%PlDOW-0iqy8!Y9*Cw1_v_CYA4j-u$t&b=`r16~T?BJAo z6j*Z=c3HstR1v=VTL%W`&)EBs2*qi%IIwCRrq*^WJCTrB#)y^6Ata9Rr#^>FIILyxEK(sq{Vvmf)yRBEB2rK}FU(C)%JA#qgj9NQ#+zE?hYgU4%5hGAUpD1T^wbB8P zm{LPc69V1%T!qe#D{?~2_j&g0`OYM2(F)nse2Qi~5Gsb?pciIS$wWL4?L66}vk0}z zJ#=rwDEGP%N*860K!s!LeX27qAY^@-&Db@=LLvKYQxbnWFDmRK4vh)ckgQZGRi|5sEng z^JoyhiZ8RAhqPG7t;cPeFvHW8IN;Gd`=g}pJn@`oSus!SP=9xGNT=?( zsJ?FZ>7Ab_GCICUcA8N(d=wyMW+D40je=e+;Q~rlbH5!d9&FXTNN&7$PrKr=<$=>G zxNH0WK3M+i2g{G)-wu*F+SM7QUGN3FBS;aq8e!~b3-VIBhl7pYEzk8VbN#jJC**^# zN;DL{eR@mi-l@ZB9iZh8ny|X!r5TiCxoiqc8^PtJJ4|%>)qETAma2X8NWYld?dFcz z#9NX3gMwCutxU zwww@*r@%swq+gN^m&Ci^HD{<=Zv9M`pC%p$;F@#6NbKb4`l8M9i}XMOT+svcpXI0 za=n?&Ww0g_dK7nRE3rha6~&3r9Ua~3wr#q1SEK=6+T3|ky+ip!t}&Uzj;}{{F7|3w zv3!mVppC_^BojEJuF_mc`5;NVcd=QiuE|T+&TmwwD#p~K%Rmy=+ubg`VI`et_03yC zkD1n+X=6>l2Ph*PxUkMXXqq5NW$upG94@@Dm$1xg>0N4r0J?-Tn(@0dIIQl;NbTF? z6k!a40FQ(7wyU>jfcx{+A5+*P@Owz;|IThuP=9Q{eAF9rS9Bp(sR6olg? zwSWMPfb93V@iBi`^XlRI#k~r7gEls~{6p{5k^@Z@GA(oCk1bUgR2#e%JNx8*Rmg;> zZ-;OPceoi7({83+W%;96aZY*-jh*a7c|b}7a|;_~EBbtA;aSo2l!Kvjkk`hTCL32x z((U-u**CsKz}sU|1Re3sU`wo)Z=Xacl2h|%AY$;im4Gw+9&n}66@etIm-M8^(VYgf z_p?lni(Pak8Q`?8pFQnxeZj83&<*`UlW*ISwv!s>@90SI@|~+2{tDYXrSPeuzB*(3 zJZ^HzfUQeYmYld}TKH@s_MX8hG#9yRbpXV>?C`$9^|KR2@N$SX3<<8+X?bfG5z=pQlAWHmV?r?B~!k zP4QobElY~tL_;f9GNl9rPe|S{F85&?p4Oz-Yl#^VlvaHnq?NmG#g*2*gpJmWQqs(0 zQ|mwC&K|z-?2xN@Y-*$ek78i>`}GMOQ0i4x^-mc@P9O<2 zUsBy#yM2>OXs%Yk-eEj;QBZLpxcR!6d3mU8=qSFjzZJzdNtGdLHByA*UK9(|9?y%L zYCGoz`0QdiePenrc9a?3oLdUw`jb&BLfm`aFNhVENdO`Db> zy?HogJ%tSsdm`Zyx!dElf~(p7WVzVaUaMc?V=X?&&?_-66F!gh2%gi2d`lF|G9hpV zHqgRCs%xi>CzX zZu|MZR7HLCuGhGeM{C;V2{!)6WXH}Ow)CrG=JsoDecymG8gM`%MKL~@NG&d^(Jb@; zLiX8u<5fbO%(gWEGY|O`b9?ySO6@&D&z993OPQ2&dm1~N>9I&xn+0i)URPrHXzP?X zWntZ}>`AL%nWf!37;_sJG)0=&=5@tHHezgO_uT%Q#CR~Z#FZ+GKJb!@k*@s__8Oqr zcZw_;sE*k>mZBLo7csFKSHoG=FY3jPNe}(>e6gXHZx*u?>5k?`+@j|<29t)29!yWP zHFHhDSTpkR*w;ou2Wn5e1+-Ici4iF&j{TV}dzr?2MbWnwY#;#x4*TF;6e4LC!kU!O zmJqIHP-5qvc?8MnzD5Z$^kD*39O(mgyoSMtDBoo$nQ zISw1NF(FJO@OTWiIu+tOq#IA}8DSHWtcgk)^H$I#f9F!`p5yAdHuuh7pPrnJQDd+$ z@LIf0)I+(5i}YL-L!*;dMkUfNM~oT_s$4qf$b0$i`Vj-(3PHk#uQcGa$*v`xZbic} zp!njvda_-3G{OgA!97V0{V15) zu9i3;PI4dctnT%xj&Ts5u$#1U=f{N*qEC9Auz48pMU8zh&1!E;n2Yn6kil=qM$K#V z6D`TmF^B!3pkJthDn@**qEs~nJGoS0X9N2daKEmCD4+ma^wGwfjy~;tD6_qT*U&cQcDe{9KA) zmmQJK&UMt`y}aZ9#~;=oAAfV@zW5|S_7yWuBLvBMt=o%(1DXb}CN0_09@_2^zj-9- zyK|avT-lPE+*`qe8xArw3wjjIf@rvHWI<4iSw);w&ICY-hpbm@;*?e&zkB8C*SMz= zJJ%hKVoEzNxKqm%^&$Pplk_oTInEa8LMh89@9I@giyqjEF4a0i+ex-)$BR)ViKEyAu5$!DH&xhXy`pI~ zYFI(0b~xKIKVCo8Bar#w`O=D=$MizAva;g?6)%K3QTrKSbhD^O(5l@DWK0L(Kf1E9 zEpIbW{qg?h_nxA~7{R2G{rKPmHii<)FZT%RxB}g6!yrHt3VaCA4EdNQ7Q^61)`BzP zRY>p#MM-{Jd)v#|7Fp^e)4c&*d__ZYc&w+(Z5vp(zD?*w;W#OK$bfDx?j+*U8}fL~ zko22DZ^xmv;)Qw-rIlI(VT~)bkK3aB-ilu#X|OVd;a*$+ zm;#R)btuJr;)9Axoz=m+1ODClxLjF=@p{H{g721xj`*MrtHdOA*No3f0O$%p#y4^j zA;NG9zFpk`+r+(&-BNjOeX8OqZt{_tH7xx7{V8tVOOJ++*^)Y<@YJwvAuyew*EIcM zC_xISxE~dB#onpGm#=Tj&?NEB^l8NWh9>B|3RzEfS&NGgoyktqXu_s=h9apw6a})` zdb>@344$*m!6%P;pJtmWTcwr`tFMVNPFEiHnv3(6fT4&pXRjI(3Z~NmM z%GEkVpyRE@oR1{P_9ZjxJKPyOgTM?n zw29Dm!@B_KV@RH=?ur%f!BXxRO{znay&QK(!j&Evc`Lqq1IzotWZ9-q0WW&jJbI{J zmXahO0X;=y+unhricn&QwN$iUf8L7A%tBAXle+=IPl)dH+Nw>jzM>AXz5IJ@U-8J= z5=RR%x(*YItc>hZiiK7sw7-D1r4!*MSn;DI?`K)l(~~fikAScKw;0V^$1}M^3q&3p za4l|}nAiA}|6nTp6f{o$N~w15q)}o^0evqN`V#0+1FaTm!Xw>nD|wmmLdC?DG8pON{4Z-LY;y=b8ohQ)-Ba>j*9sul$RK-@Gu1Z~~s(hyYF@L<(@ z?PlhdGr2|-OhLn~b4y#UJeg&HM(RMRN0HOObLk-=@FBO$6@4guw1 zJ&lJMaOY^X_Hys=JiEeX*SEsWi`kJ^E&&@ZQ)jo?00kjG!gtoNSF)39QA>dO^tM0I zOWg>%DsTnqv}(4k(4YALqN;q&Yrvo?4x1dkl|fKy#Zb+fWyzya$g0pO5MY$n2cVVS zeQEAx#IayfUaVs1#;aovO|ibotHW3Pyev%sX_Wbgw?p=0W>8R4>1_=$0S5PaO-KTPk~d=n zAl6^LA>F1z@>ealwVhn2zEo}mOsiWgvh#kQ6MaN$p#s?uW<6sq#W~VY@Yy zH>^!S+iFONuKunttCA3(Xa*z7%eSZWhW zJ-vxZgY7!vsKYNPqb!!_)%{fTqQDN0&h37#i&ob46`WyC>&2#g~0fIoAJFwJ7o6_lT>pkauC*;s~8L z^n_5wWi4USLV-^K^%Y~ft4)}1<%m)ho@2tjjdBXnm@IxXJy=-vMxeyatCIqrU|VNz(GzgFg|ANRF(<21Hg zm|$`e6Wt&?0j5Zti|T~)7?4ZjatvX!Q#Ta+zLu6c8$R;VNiS(kI;qXy^5tgx!^5=s z@}v_+fwxUBTmFj^>Hq4){J;BoJAPLY|2sGLU(e0`na%zuXQ~sWoL<^2#&~Pb^?`P7 z*65@qnIoUrbc2)gv#>zqs`>gAkji=GBOe2l6$OS>y|N42cD zPq2saXQ%VHZu$@%CQJxsk?kO>qQykI@BvThO&~ zwy+6|^>m8R+*DZ&6$5OQCxM5^6#xxm@BqTfLLe=meK;%I+Ff;HNi}-Ul_49c2+J0! zomP6978_Vn@=PF_l;4G~M0TJeg@fV{1_Zd4JhkWQ@R~P5C?MM~?;Wv(n>Z+Ep>Jt! z<8^Afr|~^m%3wjG{MtgZ8?aIU;~hkx%7P?=?H9+yHcFGz2=nMzujgv_Z&nUT4+q$2 zj9D*z>W~vi31(?Wi@i4zV*G&mkIGi(2s_A%TQ0xi(Hq8Xn+9+r^yh zF+!=26|hKkIfe|Rd}uIQC}+8%kTKqTc`w?Z1npQ4M{?74K{^~FrzM9}(Ch{x?^O&z zBYfpvengv#uB__y$amlM56M=rTyVAyaCDk*FX7o~GOywCm$bM) z&NAMC_N+!|!2Wk0N4l-MiLy71`u1{Ga)-B6OzX+9vKiFtM)2CS}@;xN-yb?i1^t$ zmV2*=k8K(Es}gXolv`xh*p+5cH;{f&xl0r?l1}P3to>Nx-1J6YC`mV-}j8ZLp>2(wvQ2X<6d>RR|Ibr15! z-sHbtC;6Q~RomvLhP47gH;a{7;;IJ0Xe5Qq-A{?guqLz2SxdGScjYxV6=l^o1w1lV zFp6o@e3y_mC)gM0RT@KaqXu(gk>j)S)*`uQw0`YZw@697B+KRE61tFsFtQ(EHtS z#2i?SbxnzfvoE~jxY;p1q2IEAN%0cW;-jfkdyBvtil;(|oKe<2j9xtF zZNm^nY@6TmXpKOx&ucw}VxT0c5YsDBC=hUglV2<)GpCQ1&jX=sr(tx_J5!GK| z1pSJ(b4aZLuK(aUD85>4{Ln0C_*z6YmwPDGiKn4@(eUi!M#gU7{s z={BLgNOl0het@EdkSsb)!qd_+#i)w}qkaAQqboG1^ho;tz&j<)6_rcJ&wdy;I?{JP zc2LsT?(C%gZqIx4XJm(t^@r2DEFHSUWe1g=>nh(2A5t4Fn}|BPy0dBn{dDUK}8Fpf-`q0FleyYs3)?R@y(>;gg<@cR;HbGi>=7#+i2>x>?`K5m~w_#UUQ za8GgeJ0(ah0GZIoJgnz`2K2k5Q_H9gIv>3ddz}awbOCc}h|GhkWk;C$J5d*>{igPl zE!H~bak=!NB%4Hs4?5cB&Ihxj<^J7H)c@(v-|^!goy4-})KG;*rCCfuCcx zV}f3KY~{6Eo96`Ny;JCo>rCU7epQ(&6rDX~_{9fjxbs{~XD#hSEf%u14-Om$HU)su zPvtYW)A3*2_mi@o>g*E%-Q*=lGWbF2bNssyWU^_pCLBWQ#_vadmYe0I9R&>#3`^7eTf<+`5hxCX5a}+VE0V#DI8`C+8i`PNg@Xy( zJq>znGj7>l)+!h*^rA*Ly5YsM_!9=2qh3D&hFE#T@gGbt^JAf;3UHu&chvi3g1oRv z70^i0?DHp+N%(cjLvP%Jw)9$&5!M17bdTAQJnr03@>%uC|IxY=C^y*BFCh&`#~I@|#MMp+)e1!Tw6Yvy zLV>m+Jr?5+y3|Q##tW_T|#xGpncN zo*NDZi@1=?7=^7eIKV6XmH*D~)I(K?tbf|BDpqRJ+z-!Og2WQbGi^_XIc&+`vWa0QXXrBB#e-HXU+v6}DkS{@* zyFp(bw8LS`Cd;D9V{0ve;I;2t`?N%z;Tfp$1H+=CC}VC}$17_qcUdkQXgz2Y_~Rcv zLbhIF@F8vkj>Mb27L;4my&i`esR<#Dgc1+ac=#c8i%9gRYae}%YviY!_xHv*B_LwI zDDvL(wF{r5ermyxtou3P7|JoS$!cUFLTy<2R3jIWox8_&Knb1Vy?UD+x#EZO5IXSq z#$AoEHAHsNy$U(svg(j9P8zQv;WE96c5a*1-CRI5Xj+_1#DfA3HXf`NDldF_kYYG?-W@po|XS7=Ym1VVvm!x5`_M5@k ziR?=?lmp{YPxSl)_Ep__C*@UE$!yluwuPthcrf<)6Z^-Mw8^ns(oG4gVniQ4_Zo(r z-msUb4Haqg0ZHIbcf3_Ae)VZdNr}>xQwy#fZ`c~S%-mwGZU(hNNtO;#4np1xUby58 zy7jFh&{e+Lc9ps?VMJz)A`W=v41|tRM%vg?tDdc`%S5qYZMv8abk0;gM08Okd>;A2 zO$clV3u>!(v!Icho_bB~jO}?JnM=PQ?LtOwL1+|hO z5P@+vQlmK3Q@aQ+cAcxOAWfs43K#F#rt_`Vi@?oX>gsD6s=2y&ja_Rv_Oz`^UEc;* zai}n363+(O*-`^h05Ef4Vi{G%A2)N{$*aizt)gU_L;R@wNkiY1l+;VI>9@@FcFc(w z?lV#hJ0njJpz-QaRHy_3(7^3)2~`bOUXP@dp z?!3>m=D8YQyA86{41@t}sQcd_RsIN_+FFvQ@I&D%c-wLNiKgE9!L$ewOX*shm{%!$ znNW$-YDZFqm=dXB#0090((2UqMXJN>WT@-_%{1Sh3M8o_ZyOz6CW=?)I857n2&KXE5*SDb69r=t2lz6qn14wmX#x`_G-ME%?wZlSSw3&HW zrB^Kfqk@W<>Rlo4quz%a?%GlO^u<9qvHS7Pv!Xk{U$))WBf8S~Y$&^^8UzeGyohMh zeoDE)hkx9#V6nU@ZZl26i8(?}(WNGSD!=Bwl(}vyP#Zk)*kpHe+#qPogo2vBEt%z0 z_@)x?INolI>N47Sg`RPHKy3GB_rWFu(@TCjauG%iLQ!nbuRlOagvwC;DHA00st(9^ zake6vd>WkvI*<`H%{&>{N)Po5>XDIO#nhL`v(c;5>nr`P0b<>aabC(DLi$JG{r!MA z$%%6!k|LXdWeAZ_*n-d_hs#L<`c$vryRY0wR4>EQ7f}9pl{15z(}jfJORq_$3eNe@ z&-O4!+ZML^e@!N`()hv{dpAh+Jr|nD==K;JAF6@oX=mc9qF^!F+gq{9=%S$sLkz;Bdd%=HS&T?W-gV- z2-t{xphfkl{5Pf6X6eYz%magsPChVyNAVI@7UG0`*W6^A%vs{;WSN^W&(-G$_l3}% zCR9HVM?k1>3z~{v1`L!v6#C^p+7@y^f&(r<5 zIDD!Qcw)kLjs9K8F%%I^SNKr02wJZGc=QkQDc!uX1p2r2+oEM(0?Dxd79Y;vyAZxN zbX+RfwxjZvxA^R#7Um0j6m^jj#VL}rp1Re^jVpH9j`MtyUw9;KmAJr)d@My$%wKD1CF?!GoVv&uj0=i{LOvo1erMqog2*x-fesj zpnV^ndaeMHp|9n-?1)AnBu_#5k!(JC0ca3+O@-NC;9TD*!%1`Jci^HTvTpOrKNW zP*8ddbfCHXI&e1-KK|~S|6!02(yvnik?(JT&@W?z5`LWt2=9K2gnk_)68ndl{8J?K zN8^I@dc+@R@*h$C-vBN+t4UYkxWABu4X?5qJ-$x4s-adb$ZYxFy zAvpt~%Br=2s%N!v-L@2*4Vx(sQmSlt1IOa!1B;3{marJv^=w!*)3iQMZuY6iJaUiy zqQh-R=*5_sms%Y3_-eUQEh!q5+?h`ZQSXzdJ9JoUrHS>$v ze$jN#jpG;J2WfrF#>h2mfH^xLT~YV!)qq6Slt-J^>CqXgnRFUWI=wkEJEZdB;3|4m zVO_E==~M3ow|2FCR+3Z4aJ}Y^=$FJaO#$+i-1PA{C6BFjmC$kWI@YW+kJ4H#K?P_aco^EHWdi_@*RAnskgKP z^}METO|9=#{*9qs+&7MRs@ie|;6r@B;398l|auFmxAe8W6>V z2b269V#N<21vt5>efZ1C=hN>Nz1rrF^K`1ervpD~EwqqCoZGGRXtuu_`f?W$%}s^Q ztkVuNG%6WmBe$DGR&jCY$U{k=RxOUTE*ObDyo7kC*~M~QS0m%d-gj9YS(BUf@*8?s z2+0gGPN!**W$dUQUs7`j0C~8t%EN)n;|?;`Q?j~I-E1-CU|p@D)mo}^lD_!C!fDrx zherhOTj9EBd?p0f@KA0Tl85FGsJXO&MnOv49Ahj4!6?H7CO+|xM{ zMbWId0Ks_dAa}^c}_-4b;oo?>POI6)*;PnmQy~f1~k>%&jmbr2_^;*>YJB{y)`%lO`o*0;8i82*Rtk``4O0wYGOGQxCwk&kSqJncbb;vxd~lLU=^i)l7ozq)k^YOhEXd?#|Lep}cUjZ$)trXLh}%HIP6M zkEbkyh2``HEUsJ#KjO@cmjyv3v*5LM@uIpqejNUw%cy+h@Zin*@P*U`-2Chp#)ko} z-E%Bv*c;*e0?@1_xx(%xu{{T4AEn=_ITMxd?HqW6rvqX`Q;k zhDh16nC*`OW$RFWSh)v;r&0SA+^^5|%Pi_zLv){7XoFdvGxKcOX*9SCBHsQ-tWZb= zu>xzV1MNhlB1G&m4{L!aBp3_b;V4KH_A!pJsV$G6_A%+}1=WD`FK+_cl>F{FJt|lLj zK~uvlhDtU=u3oD4uxfs%ke5ua?{n*ZP>E%J`0~`{-h{CPs%HX-w4%{JBduT%X?4B+ zlcA!T#;nB+x5XJf($WhfsVlXg+!nH#?q0I$1qh@aoaZi5Asn8 zwy$-4%L){d&eA}p=0Q5L^#sxbKOs-lYY!rY7Gy1l3XxF{OOzcr_0ZG=%fW0?$tIgG zrQpU;)poEKI&^YSr`c*u*--*~J?EP%)Uy8?Ffh55l&Wbnhbn zT<0seRa!R>C33)UWiOx*o`Bs5 zF_u@2mr*#=Zu<1Vskp$m?e&j$d_(^wBPQG}TTAFm1d(D=ImxwanT{lUi&C-kApl}n z$4mm0~JTd^tJ*C5=NsRL|$|GphdrqWT0=u&omRBdRw8Q9b8T4E3wLVcA*( z>Y+K5q=QO89cVm6PQWtM)3BM$5H8w|EULeWk($FtnwgY(U)1Z~*Cii^w@Mm~$wr4B z)#r=88SAY#(0WV7Y@Y^;$bfMg*;Yh!FJ0dK!Q+9M`@j*`mMFG zLkL<$MEO;Fk!Mmi&vHIi-Hp@Y@+=a`Ini^ZGD`f|0d6)?Ia(13>=ZT7xiA7QvtFWrAmX0D&?nGUnCu-AU+B*wr;H zN8-pMtVf6+GTG-*>sH`VbSB*$;{1K|ZZWsIWOHw;T2gfTN%?!G1)JPUL7NsEbp*_W zJf)XpvNF1DOT}VC)rOi6FaBWKE#%oKGK)N5H4c*tDX^YM8#(mEhRx=5YTK1^ZHZ#T zqpjID0@t*{!A1CqUec_=7zsT_Z6aY>@jRtp>1xhRk zl>S4j?=>UjNBgh5b&HX$!-ta7QCT?R8O1r;C zcOl0nh_$Om1)*a|L8MEs1<{12fZ0c7(-}%N;aRdilNSbSKH3PgH#*9GS|O`0THfa{ z>{=*=o2VMnrBVXmw&&?+EeV7IyxM!AI;K=0jEPqOBG$RzKlA)@V zR$0iBjD1{Wff?2ghuE!}q8zH8aXR4G{}h9e_sVjwpCfe_XrbLnR@ON%QtevKg;ax^ zQtu?%Gwpvcc~Z^DN|YLKyYto>&{Mu*qVtKAL|=lPcDt5JZJKuFAc54NnRxh#LSB{K z_eSI?Hje_=wC>oR#&|bhHdN&`iw)N8-N;r$Bn%mksb0ro!o`)zxFz+jXeESsvjVAl zBoPM7vb1#5b$j`Sw17Tf{&CmjqZ|!yC7~Sd2C1EzqZ31*cfGWk4?HAPl+m|LwnSX2 zB&WQpETL9ny|SzH}k=ko|zqeME74! zB5M2N)Jah#Hpj05yKxlR#Fe zMooOGh?+wDU^=3tJ{ctyiSUr6`_Y=|Uphr_N0gz=DDtPFgDe#Sy z&AY9)5dg)`yhV?~xFw8bU{xV(pr=_4%Q#AMj;oq4If{@|OfHyq58|jWKn5WdOAtf7 z@;d&n6G>72jw_IB{2Jp{tzqI(iPkLkDhaH!}LS)spEbdfcmy{M8La z*G3~=>3!c@imSJXNP-Tyd9DID^Zn3cpuC{w0N~6a5Yk5|fHMmKIJ0B`fHPZs7)G6& z5_jD`!FUTyy)r)oebk_7T|e3mi3&aVk!DyxO*ew}=rlFar_vR2OqAA+Dh%#%dek4m zm7Fqt_PY~B0oWhG7(-Qvl`z7Ux)gS`r&@m<$uC?U1z|V-@f!2UkzO~B->mf=ReZq%yP%c zJUlc&1420-PKPV!*)n>bcr4e}rKB>Oic^WEZ|*1U*+7r=F!qjaTQYjABMM-%Ch@{b zahv@DOKSD`F>4vEgO>0x+xkYmv+D)yH=G}}?K^rTb=ubSU>uj8%D2(KI7SP-Pv{m5 zRXV7>KjIr|H;soZPi(iBr3RCB)7-^5hZHuMhXTw~<*im`?6fZ%7VzJUkeiTaZ`^rf zM{?kCYh(qI#)GGTK02*q0R2>2OYX-qlrp;1mzKqk);EwYJzf^hJx(jPmR_d}$M~=` zLhEZT)E;lElQ{9doxc88Ui83vAY0Bq(8hmdd!@;*X#CG;NxCsXSIS~9S#`#Zy;9ocb z{wW&y<+Ozoewoid2ZDc_{y!i4f1Cbay6SI{^=L0X-N&q$kS!RgpUnX0b|RslPaE)= zC4$6iyr%ps57jO6a6(C7=i03Kpi)&LCGPyPVG^%S^Ml>VavpLw?mw8h`9LSc=R*BX zfO7tCMaRSXd)Kurx*tuIwTSxq!lETpjGoab<`hu0^n-~fK&L#tv(0UFZEm3WUfuBf zE5_vWxh>g{Y5kYq-z+-_BRHw8H{3~5T4rw$!e-UxZ6 zH6n08&ciFQC`X-N7kWxiH7meRbY&&<^Oc(xpMtPZTylpN7yX_RkQQ8z8GTp0Y|ZU) zxoUy0R-jhZI=mw#`zc|E*{j=894)&S`uV<_K<;ZDr*V?h9)*g-zv&KFVE_uUi&zt> zSm_V*{Y1^c#)&Mu@K>k%%Aj`nT=OdxIBoy1+W6bB=nB&4!ff(owjw7#&xg@2W*km$ zCwY^0blGxqs?Y}Ad}i^{(`RZ((qF6R`|fX>E%Q$w45;^t=r@Etg#MW|m9qCKnkWh)Mmp^~P@t~@i zjo_(3VSz5ntyw)}lyxon2|sYJfJ)W4Tj);Jnr`Qz)g1GLD>puS zFYM$Vb?teqSFM^DW^gs|Qs{tv*Qx>^l`spz1(^=KBxxmQ(~z}kZMe;J?2`RyRrT93 z?DH>5s>)!k=3HKT9VNTXFPuC^AM=_V-K#|7WhK@|YKc#J;006~9QH2N*R~Rf?EKSk zN0Tb}{rtvgx$7Jc8!pB8D2?~cn|Y>m&gxY-u5xXs=!D9ma59vasPkl{j?Xmjfibv6 zhrPgHXSDM2N%pClBJmfL@FXXJ=XDmc3uBYu zO#2w#Uoq6nz)5dt1j~wDo(@V=dyq64Jb&l}y(ppbQ*T($avz;KUb`?A*GO#Mq9=N* zWN?lZ5f!EiZ4C&rK8^YeHX|cpqiNA=hu`zo?bdzxVw?ZEK>`!)P5zO<^H&?nw_-d3 zyzY95%|DM(J}C>IJ1=Bq3Ht1qx!y|Tqk(&T4^!3E4&kI-pq>LKjV;-%su@CNjYJ&x z@OTNo4a2~y>+1#wVaTeZ>73Ph4ao~ql+wpo!OK0pw;gKJRtv~%Gd`Uzq<*Z=0lP6< zH}dC-{=BKu46!)k^yFj4m3|(F$%rT`XAhX9Oc~GA>V_2>wKDm=Z3`lLy5Gi$N!_f zD-UY&+M}Q-+d~WzA#6dmpaCPRfJm?u0_OrfB2@I&YO<^esjO&&U|+}=lssOu!(M6 zYEZu+IJp-pjy%z7OHB~Pw5t$(CD;+TWb3!Oh}*gQv{1*j{nN(Ax4Z5%N%M|iys*bTu=irdL&?Z`aKb2>T@t~^8P0kD}IaV~c@zd^M8 zf)HnYbvvH1;~7kECCPGGriAcBk&MV)YC%k{OUa;*w0@&Y>}KylYf93|^ZcY1L8-Q? z{Mg5-WF{z)3=Rs!z5Z~j`dUZUZZ(Q*{O~0=(&@8?FZP-ZCfyyH2m_wLj{h|3Wt>B9WFPA4(2;hq;mr|jZ8IuCj1`ng ztZ;o)V?m2PIb*_H=XvXyt2ef+au!?5Rs{MNWI;Q`pGOi;Sw0?w9A!$P@t_FcxGISII$!gNNTanM`hm_33u{3~!spDNm2&V&01nm1WtViZdXm z!>yF*DfeYA?T<~l3wtlf?}TN0`Tx=Zj$5J#y)N;WumZnrY8Ley)c2fQVUIw(vmQ5H z`bv=&p}OR`G&BV`u+DhL2R2@BBDr86qGs%?`mV&lv`|jUJ2pXYZ@L_Lh})R2L}8Yv z%h54D`7A$DO^tt;ms9+ZE$U1|^aS!jZ$kj(y2}!j=A2cHZxFa-Mk9zZa!5Hlz z%P;L1rb~Y<8X|T+pFRTqMfQX{fTT}Jja^N?gfa{wfPA<9EUSjlM zD&hf<&4dL;&nOogBpjHXwZPh8Jnh+JL(@vF3CtKu>qSIhWNa{8Tciw%UJSXV!NrXy;mqAg-*ap{CE=q0&H<1S(ROKt* zId73pO*sgirAck!xA7n4$j`whK1Pi;eFF$D(5dYA3S#!+%4bFZ_}y#w4zrWWjOFXX z7Zp9ler-e%w-ZEW*n~s@C!e^o5Xqi5kuHo;lr<%yFfe@H?8A!mAI!S7t`lTsR}3I? z3(+F?7T~TT3ru+&Me-eUtdlUQ;UgQB0F2n+^;)C-HfyPayAu$NdmXRrT!mbsPOq?) z2cIM2(G+Q85Ft&vrr85<3ti|x=zhoyx?+9cIrN0b{F*n@ zvnM5K=m>#3sllK-?>>QBIhtP|uuIBQl3_Lw!9x1`p2Gj@orM)ohqMS$C#yko9&ypD zod0QpfrAM~fuKFxF7ac{1#QfF+GHw1r$0u3L+mlwjFGBeC}yIR{}w{sv{2Zp1=Qw= zH){u2D5bHX#0j}Hi;$opSDkcsBi(Bid(`YIiRPF@Y|=lCrTRM-5ZbSW5nm#L{*s8K U|LBhY$VKqWwg26X@yEfR0O$`-od5s; literal 0 HcmV?d00001 diff --git a/docs/source/images/cloud-dedicated/resource-selection.jpg b/docs/source/images/cloud-dedicated/resource-selection.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8e41770a7af4ccf39bc0fbb42c8686a160bcb84f GIT binary patch literal 74443 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 literal 0 HcmV?d00001 diff --git a/docs/source/images/cloud-dedicated/resource-share-summary.jpg b/docs/source/images/cloud-dedicated/resource-share-summary.jpg new file mode 100644 index 0000000000000000000000000000000000000000..03073f86f9d9581ef773eb0d7fed4cb502b65ad6 GIT binary patch literal 42242 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 literal 0 HcmV?d00001 diff --git a/docs/source/images/cloud-dedicated/service-identifiers.jpg b/docs/source/images/cloud-dedicated/service-identifiers.jpg new file mode 100644 index 0000000000000000000000000000000000000000..57855ea476a90b973ea0fffec00a622db9b4d545 GIT binary patch literal 96953 zcmeFZcU)6X*Do5RNfRm3AxM?3^d<;M6A@AAB_dJ+hKRHvfhfHrARr(hO*%*mQUin{ z0wP6_P!o!PlmrC=fpGJC&OPtB=l$!s_pkHb&%5@Xo!NW#O!k^tv-Zq)t=Z>4&zAw0 z?--dH0jQ_|029gvIL88P4Pjt+0KnWFAPoQjE&?u4u>+_nF)GRihyep={uKuRBq+ZC z0QCo||CRdT!v9RA7WqK^KjRmk{&VB`4nY0BC)6M6=Lvl-tR#OOpssIfPV-M`6#7?O z{9n<_Q-X=JDS!r=%~uTXwu$;-=iLCdix-|!i%?UE04}gmQL|B<_W^*EC!(eL7yT<6 zB)<521YJ!9$r3i3CU|x(#k5TYU&!A2Dc53j7?1MJbYwjZDVU^ z@A}lu-NO^?<>wy|7z7J`84(#39TOWDpO*eMBQxt=c1}@oN$JP3@`}oa#-?Uu%jed% zUUXmoz~GmmuM?9~Kc;7X&SJ2*mDRQNUmKfSg#AB%4-Sur$0z^rMXAsK!4~ECKREkO ze6dmZxw6ePl^)=)Jb5wB z$R(zX6({_|+P^sa_ZSQR|HRpUF!sOrngbY6gzO)>K-sA;T%a@+HHB#CX#OEOdb)oR z{r^oD|3wV{5YvCqIi(P)e{xb&(^7V(i*y(NBkkXgoG(zsQt2E6V5X*`2op6MKo>yX zKIJik>6*H0NPJ^G1K5~3j)kLE%_k7Qzy5P-ZXV8ft>_Icr{%5x$^lpqru6wUh{x+| z!}SaMVZTW0t#wWF=YTPz(=p=oIUotK`r-%b_aWkpc}B^ex8VFcdAsAvIY7iG{T$$Y zAF*+v&1)V0pDsMRYzfK&;q51kPuYuCl65!ibI$=r;$fCB4>F?$q4DtES-7sN!mQt+ z2|lo3MIiymeJWGdQ)*oObsUU*Za>#6WY_oN_Dv6|L*vD?s-6{Za1fa-W_k0Khik1!w-ggFQA?l z5EY<k7tHP^UH`HC$B|k_v35zCz1SC0 z-DT&Kz9Ih<@#wG3ehf~5D3^80S=KK^Mf^p0xa`r(O6LT#SyqeN`@7)rXexj|MKOd) z3dtEi?gSiTt1{Wo*6z5@#4BwOOus`q2hcK|b&#b`ozG&mLrH4j=`P>|St`NF@9yNK zI$s)1WR-9u$uPQfji;ya^+zis;p5k{@kyUWO3>NB8F;=nUfEeG1>4v5Bb*rT@bG1h zU2CFq^C!qh7rMRc1N`CGz+Z{$pKlr;rk>?Br3fyb%KzvH!488sz{m!WGnm5*IfQ_E zvj?XrXYL56irzlXp4E?9eQ&e;li0IzmGX4S_?CzcH+({G65*Rg_{3ISjUEC<^D5PnhG?rZ|AFm<`En?ut*gftI>-=l@jI*wakD!4@2Pe#( z#vWzJ*NzugrN0{MGteQukF8_KjFV837`aEc;TIY@+t|}}311MWBe%(6_E8Ua)7p%c zk@#|8JSAK1$B(|nkeI;Zpb^12Us>DAuB4b#?wJ*F)G5c&3UG(Ik_hUxFY8l?(2<(# zxEbhwQ{QZl#p{!oQfzTYQ@#f8De{7O@o3l;+c&mFbsoa&#s@bH5!cTFP28tkL1ab- zk~*Aif-DF3B65Eq(&~u7vMk0scztWU!G2|PcFuaTb-|V9?)!>6eUP=t$m1}VA*l$G zH;D!Q=#Ppo?McDWHKHE~A)ez;s$EXU@)r5 zX8X8$QBcc-uoP2U%e5GS=F}{0{M>?E_+{4oRB|}M6$))@zh}}@8x`KCZdCbk-nn9~ z(fiNcmEhznk21Keq>P3>ZtqTbBP6>1%wDS-OPNKH8L#3CR!|YmdvRo`tUGw!s3y|i zhRMBVh|lQL_Qj`wQM!W=V;wswfinNtASs#A(BH-0n!2$~xsVX_(eowSMWaTCd513z z{jxra)yXAQQUc)&G*&Aww(qeQm&QgU+#9P!cGfnvZM8Vuyt_X?N1sy4_w!D?Wm?&fmX|~ZU;vP$R_UiWo&ix|0tPxvgl3rpI-Ic|( z>spt15T=hFKJ<1`MyM`PBbMKQnp+aPzaS6s-EmU~#j9jqGtI5$4oD0-fr>6YO!~mC0|fqX zM;q+t&EU#ky}rQalQP_9Bp##N;r9o)*%e>s+5a`=7Zj^-%C38uj0bLKkeuLj(<&&I zp=x;OOmp5t^dAF1|LN)PTl^jMuu-qtWTii`Y4^1_9D@c6h@yKtA+_Xhhz30(2X2h% zC*1lh3zy>M6}@iGdOy2s0CZGAUr=xV9l$K@xSU{hHFZ7qj$9VaGd| zqWX;R#;2SzD?W8tjr6-juY9hVnkKOP_>!H1%&>U1(k+|q);AEvdt%*d-a}#3h@NY@ zo+(l1fCl3oUpz-2-%O0ew9d`nLLyVzx+PE~@wcBAMNDrAGWpkS z$j58^d{KNHKpZ~@(5MngxRhCs!)J|nqtfLhGhA7>pbkW5$l?iW0P7L@W@OkE6RwEvc4^(ydQY}5ftBl7TDyFhdY`eWN66U1RJacOr0v?k4`zXR)FYpK!h$G zM42B!=iMbs1pC#QR&JhDj+_`(=Aehx+P}!14yMgAK4Uk0HQUphv{VAD=iVmOg$*Mb z>7%;nVa1j)kEZ-Rclp*sAdAM?0lwmBv5@X3u}?8PQF2LhHd@9%njVh8QuvdLHlB#R zcYKfBnqNDT)Nq)d6Zib8ZY)3SU44&B&Qwp&X~E9ueb`}z{@&NE(e}5NhA`vF|KBLU ziGNE0?#JxZuPDR|(Vpcuvv@3jD-%k>IV71GO>WnT$4Mkhpr+(@-Zhvcm)`lJcWeq+ z^@~5&?M1YB#2=ty+upYgHB4}$b(q1;JJgTb;s+K7`>uP*cqvb%d5$}U>S zXjk=ja8QT_U)C4O09RSjvOvzt{ixYU2^l1jq|$I)BhPB~&G=N6A`&m_2_Lg2p`O;w z?%{y(DtmmyGIWJ}4K73`RQF+feDKa{KEJ7J&INeIW!cmr&Swqf>@4wWkEv{Ujix;_ z^LA6-!+|8&Z?g9HzfF{37G(Ee)U1ETnT@2mRgHY&9YS5sFpb^eGT<<7x;(wH<+q;( z@Y0k#d`gQQ zYh&yA7;C@2E|?s*VD*fOT0&V>UsY)xzV>jBFc&E6TkaEjbag3oGePW+Dfcla?NMDMjC@t?T;ZM1No0+R%@?xdtl#_ zKk2<9s>oyB7ND zus&epy%sRo&9`vDq2?|3biK;QDufq~;{{nmryZ$W0cEth4Erf1-#AH>&zkru0gHg>+MXyIgf#y%vNuF+hq55L~n2q zF4P#EP^MFpq|KuEO=h#!e4|;RaVY<0#UW%ZPQX=VM@R51S=R%_Y$3OkpC05F;9CxU zSv{kMDLvTUclI0^^AI(?iLT!_6Oa#Nd)564Fhj7}F2l7GFbVfVtkW?NAW2dES}W zF#NnukTfLT+xT@)l!4DiQa0?6j*b=*?v*2Gx5&z3FnS_LV<=D-M&HmuTIacMS1GZ{=R?q0q(bK+hK%(;R_-UU~oNc3;xc7{+*&P zpZdyl?7REXW^c?ObBO{`yBk7>Wtn9=bvW;kie@?Q?iw)mjN5ub`zDTQZ$}JVt>R=U zmtZW2N@K>)4Fw6j817P)6c>HW0%_SP_Q~hOp9A7qWBB=YTW~jl!zA0YnN!hC`1;*r zkXqiMETnsOJph7ItNp#yfa<1H5&S+Vk?&iEa?T89CxAh9alW)o6oM z{Xw+DEt+1N*$*Gqe-3CY5t7duC^l;K9+KbN%T%4(Gp|xcY0X3Ne5t8MEI zKYbk40}BLpnB(hK#!@HeDm-i7pb@nuh{AKqgYO_7Q-ob%~ zVvo=ZUI=#Blj(pdpJ$M!+1gsDyn;j~W^@f^wTQFhjc=M@U(JFnDG4z9wn4Y+@JvP% z0eP%<@Y{ihT~}v{3929Bl)FbO4U~fzRQHsmxom$#-m$*=WiI-$SucsUbRIuybNI7s zyo-m}xU%yrGUZe_44A()FmMd*>70Vf)fweqz+9vt?G~S9Q*Jz`yXz{_30l_O;ix!u z#Y1B|49a0%p_(N03@a593HFHpd-1_jZ#y61CXa>B0|rL9Pam-INQ@3{$KdI9K^zHr zLf9Sn6Zv~JPXhSIK8=dc#pGBu|LKVR7<7N}nP&qXFEfMK2{2rT6{g!Q#MOz9j#I7h z1(*A9bQM-EF3r2VF^&niPPevb&;+h@43gf@k! z)dDBH<4Im-@rQ&D4m&vp4P%@(OuX!FHvV@-`S+<9P5WncpPU0`_g9Qj6LtP`q>5(# zVYA}^raXIcsHu-Xe%On!IP`qx#=9%Ct_;EeC1&_&!CgxKL-Q*{BA6ublHKiE-Wrb` z;+{=fW(MOzs$#%SyW;M_s|uoAfwCih=AZxGdfQf@utZ)6M{OijeSn|lw z)G~XE)l@W>WrjQSNSDICg~>F=kM*^MRfQr4oD}WcW&)IMj=tSlSLy6q^7P$$F5ay+sD%KV}r>h1e39)n=~u{V|0y8kEJ3|Bg zSd4tpsJowa=tophO{v^q-LbVA2_T`T zkBHp(l@;-U^l}(xaRcP}z)Yebq-@D?b0%;-fa#j)j(Gg7hHF$af&A2>!k3-Zeg=9B zg~^?DRiDaL!z`bEuO3Z_E&9IJhRl8F*<7Pbf~+LL=cv54w2Otmgv8EvKY8`q(Ie>` z02zha;dPTla_>SJyoC6s{*qk4TtyXiv86vgG_ntS`#pJL;%+=Imb7b`ij1)lPALy4 z_&IzCBhaB(;{qTO`wrzZ=In^R=`+{XP*Ld5)mFpLOun*Ox9lV?{UXLy$m_bMP+$kk z)+wmUjv~oA_o2zvG;?EXR0j-;Y)#%*F9g>L7REZ>PJ0_$S%3ec^o@J?Z5fke6xL(M zDFlDGMP^OdH`9rzfc+k5vz?Lm(GB{TBn>V@BA?2nrO-Tx#iPNA@|UnF_Jq2@0(LJ% z!%>uuin&V&Hn)y#%UMX|+agZlb2Q5X@}i1O@Z*5vqBpz`hnW@cU)NP}gZrH&XsZ#l z(CKg`d`)L&9=3p!7^kg=EA&57;~17U7uY)#2Qypmy|7AizhCT~#+l~*8^L#~jSuQG zrvoy>dcQdR)C&NI28fGeLJ(pL;Bb*p-K4|>dv>?w};;cGM7`D=n zVC`@#2790vsd5KSqO;FR+Fpkw-Ckc?OYV0qvG=y7l?Ork)PnBMU35<~v&BU(Go;;0?bsN8Z`w0BqZzb~AnAa0 zFFzsXmTfflS2}Dx^um9bQqUQ^a`3gmT+=>y$=&9S7F0wbS3~=c-3fHtiF6a3&oQM< zbt$*p^n=%p61k7&)n4qgXih(|txSCLkO?P6r|gG6S3R4IhkxJZ%JN$;h$}z_4ML>< zJjBb#EO+YOC8$Q>QkXV_EQc$P4<|6NaJPNr7dbtf=X|_62CKhbW?!e;M_{;DJa(w6 zErRjCdo2Q70}uobL;M;(!j3D+N4{w;1lio!8vVsg;DMHA(+Hnl%T+{hv#tpoL{fos z6Bfo|>rTx|lv{M9LsgxOV70Zv8LJcg0l5Q&J2gzb^HutmDFlxDbL0^O&CXi*>ZanT zN>`m*U3KH)g1L;BeLx#VPpczcNlW%xr9qlN(l_3?CsKy~bh%rw%s7&xc^Ry0ZrQyM z`%C9W3*lx<^qd9cmW8P8&9b>mJro*OshZzJ%`I3y-yT9 zxwrq^DRR=$aCS@ZYOBmhGjb83eZz6|na3tRgf`d6q7RhdEI|a}ow`I}Xp8Z`XU?LG zrfvaM%BnK56Ok7cbiO*p(MxmvY;5_;Evd4<6pnx@aGc&tN9za?gO_6!4tBzR_gOzM zkf?TP2nVrhGj7ZCO^&2VWd^uGuR2-KYNj5H#pwV}l?XxT5Zx$e@$kbVv&pjPt!dK$ zeq>klI>tg(D(&y+VWG6HG}#9`sRgUnjah1#=^l&1e9Wzd$rz_C9+_rY=3|2Ed}>SB zx5ze_1x#>>qVfRGki2cU;%D&&NhYsm{=3AG0aObjNk{th;&cFOxDZ!J$T~432$!dS z7<$(pnYvyxaw8%1)0Y_~vCMt-bHIakt9#3%O`%#iRt&uZ(E(459gO9;i{K!p4?v1N z4^{W)6CUM|PnJeK@?WI!d>4D6bv5j-&x}xeeUzNH`}E5>xBy8OZOb!YEed%$Ai7P%}XhTgtb953;nI!zP9z|6;`%Q z)uHk&Uk8WTBtE9#Y%Y^(bZ7zl<=iw=BMpT&bY(H;0BFs_L1%&QP#qxbnzPr@qR>=_ zd8O^bmj0~lv%l?`jTx@*^b`t2za`curB+zBW-HQ$nqg71xyuESa2xPS61|aUvjhK` z!J}yG?yj3lP-Wkn1(VxppIoJlUPaT$D}G=%Jw~kTZ3`9>fAzEh(Wpqxu()FI$y2_h z$^}rKzQgeCsa3_V-#gTNdEd5c<%WchbBPuul{&L*3mrsGB9=cOHDh`UI8N`M10t<& zgIH`~4~}cPelom+74Zk_$LvQhiH`NCYaRY#%GWR(oAYoY`uf!w2YfWEv`6$pDd=OR z_Y7{>Y|^?%Zp8QIXmex{=i9HhF9c{;?G==Ul%KuUb+77_yf>+GCcTTF-ORDh))_V0 zpO%>#FSgwg!Z8J}#M_B5?JHG?>fYJaHYJI`842c@Wgoq`G!waU)(&5RM#cg_0!B+Q7;RAD;Bm6R*|Ps0;fUvh`y)}8nM<6B;Fz};LA>F zzIt_z`E|_Y{fcl?!4*5+H?py1wETO!pbwAF-iI;S+d6^+bNKop0d;e*e3J=q2BP`d zX@SIJ>eE7?!D@_`$rr+hH=FacK15gMIQOhw$S> zvHf(h3YX-ILtodE_FQIv9%l^zd34nJNz~p5e$c&!$x|m_L~KG}EV7u!3fegrip&^nD9fTVk16L&QU~*TH4Z3uthh`2Hh3ZKx)f zd4m-FnqRn4bTjGssS!T29_OSr0A!WhDa7BaDcU^Q{_d^sD`5Zo7INRAZuauX?_U*} zs{0ww_1gpL+{Y0vW3#yi`1J~`x<7wHuAuYuL~lU*RGm-Wvu!sHhdH!ZV?t!5N@!RzPZ>nEu6IXl`qISh&LEDh&lOiHN69w)l|HZadJw! z=Q~d^HPKQNZl7Eth6#@9G^(OXJykP@-~@Zet~$;!4)GtOB|v2egK5^+s|++s7nBa# z!$wflpj+doa;o8JnMrT;JDCn25EVZB z1Y;f}r|NJMDl+EweO{Uag>cAjHFbg?@8{3yUPfY%MS-Het)>@p->QA8kze;1046W$ z5FI|k_$?;kSB08!AU@|LHIjykcsRdzDp+Om98l6BrtRq>?J)enW}WfgWuim@2{BfA zdT*+Ox&$V4^dRQWlnM(USXMkUB)xp|lc{WceQ37JzP;^e$BW#kCu^ojk9O+vn@(pg(TiU7>U zKt~8aP!NP$V&B>+vD2UTHqOc;l?#*LZDH zRi5ts9NeG#5mxCBvTRW4kGM1Ic^;=i^OqN-;w3!4Gw4T&xu$1%>DI?=|1Kwn+`^*{ zRYq&dqKi6O>PbSSA>In<#Be{R4Kb$8#LgGa0Q;ZdA3=N4@5aE4+8xXIl+ zyn?teXXl--qNW747PU%)MdejX$)-7u(k3PeM2y^K8|3_Idxrn;>BPGi*a+>>y#Th) zjKStHs#hN*i45y?M%#VNlbCGUC<$MrV{cCsd(oDD^j__o?TUZ^qTZ(aqPEsYqWkou zO}rfY%8usK-?du^uX?B~8i`riarVFQ?i-rZr`*^|jQSqFtGB5=-**`}_vFtYi1Snp zPyW*zgH~M>nS8eQp#apLHn5H}E5Dm&;K9)Bxhu2~lO>%STk_4$GAsS46uzmuU4eK1 z)5iyjJy2IM+w^yjH&chI)EKQ}q?Qwgl6`4f6xj0azmd51blz-t>5ok#QMdOc@D;@& zji`V&6|)b^^2wYYl5M#6o72@RLachXkLt&}^xu|}LQygYns=@hmADvk-lzJ15$J!_ z{cmn{PHO+#=|5g}lmCvz^RlHO=c{W)@qquz;q-t|cbaV9auzmr4k*l7_x|{w&JC2# zr^tJ7wo-f3rj%&rVQA+($W#=V`a zRC{;}ejbAUPLj#G=YT85hc~m%l+OXElygA8bsneF>+Jt$_D2ZUS;V9TiFgh;wE~YD z{`~LE|6O7KEhGTKe|L=kRtEoPY0u-j6@S}PaMeI3*Wohr`@gAGS+!Mzpna|1x(8>z z=YV3qR{KV!^B?3t9ZVEQbt4Mq>`d`RK9TdTthMPz?TdLX9jrjl0Y%eomCr6exNz~y zdY9f=C&FVX7SXJ*U4UD9UBK93q^(frZ8^v9J!Jp1C4GB_?cQMv-R#PH2d5GURQE0R zw1S_PR7OxTKdZ7iAE%6V{h*E?YG+$O^6KPb-&~4gZs)%5I^b-=`AZ`>n z{7M4R`1K7chfU0VNO{U9a`sHa5;VpdcMkAUAYL0or$ipLu}qgCAQf8(4s8x>0W+*@ zAfFG}khwnCH#z7Xn8g=bl4>m6{H~srUw@3he4d9(CzUXH*m_o}>oV#`agqy@gH^J| z@~t=H_vfsLL2!&)SN7o&XX)1FLrm}uw~J|86o>g#SJ^%pl(-&x)y41Vt|`Apk}a3x zQ;*b~P=s0m2gQT4E}3G54eAFawQ)zvD_an4PrlXQBYKScZ8V>T&>o`Lnse{BCyQRp zc3BWbb0`*ZF&(`qn?r!>l7Psd?t(ZJ6T-Dd0VmXgV}bVP1fp;(5Bqb}qMpegM7Kmr1ivoalda9dfF zwjVyXPe`q`OOr+uF2vtHZk~``XtJ7Sw=*p>puoBRWqUllnrhDMt$f(#IA|mt(W6Ic ziMp7ui^Kz#g2d*%D+)1WHdLQ3ledmM{;iHcdrP~iM-1DXTnB?MSfu)ak(+@?-q+Q` zqs@acqLkdsjz$PcQ*y9f9n!22y}2?q^#q^sCjT2jKIbRKzWB=qver&8sk=3IO}aro z=;3N;@2|bkE2sU2l*t|684~4LqlHDhCUZD@ISbA-LnAbe`^@kBLJJAD%!s3=RZQJl zlDXq|kPf!hncpUOdfpxvUYT@XIlD{&Y>ZRjP`p_WS&3LttQG^esPfF@&gptfTyRBb zUp%@jz(KCmADa4Gf}38>8?!2kmp0}=~O?l3kY|4P;?Xc+IQQS^GKO)1@nXGgZb_Pzi zi%{|U7$cfr(>n5DBj6sx10{`Ln1DJ$Jw=z;yZ13H?Ay zM3>AD9K|Lb)nQlcWpi{n^rMWo15qLyI{@#${i6TIx8)o0DlDuL#3a%c@`x_C2w@w@ zt}S(`wt%B}(v={b6O!^5wf)L4{o}0h>}m^XdT(G(5}G5nce#gsI|3G_xlpxunu_5%1TJ)}@O+ym0v-@i7^{VF+ ztZ#)FsvY){LA1)l!=btl2+?s+-(XLL<#;E3nqbHsUYakZJ)ZFwNQ1*o9_q#SzaKwD zFX8V3e>S4Kgb2XshiLogVkmCul5S*xor*caddf#~TreRt(IOyNwtgTIrz`iPSU`$e zd?)z)^Z3jlUrFlHS^gJri<)a-Y{NM`k)i&I% z$XnBE-n4Yi>t$48(73t$d&xLADV+(%;9%h_tIhBCkK4jM@vN6A21=!KfGgrM4BDf^ z6M@b;QG{zw7)5+=+Q?b2DB0p_vl-4c>TGO}-ty#sl9qmFIkkPy59CesK(|>$YO9qI z&2AYd51Jw4CuYS`*8}2dFTO5G&7O~Lus6gV~T^k z!|c=znFHK%ubmQU#3!djRu`k#*+1&Wt8qU)7H1+b}$nE*|>=)dkHw}%k3b9M9a0J*7 zv1}f4Z~8+cLLO(vR9^c)QeelA|N6u2=boQ-1O07Sya~G4n!nG@-Ee}6PunQs$7S~U zov9la^}H0zAN`UfiueVoU~`ssQt`&ULF+&sFJxOl$w_lphARvTaf|-F!$p`+c;%X% z_+0u${qe-11ES;=}=|nSMtOLceHsd&Ps&JUq#z0qEVK2kk{5j+aHqAXT zeDhQ`Fue);n)BG!Pju;8ZQ$>IGDm&$WL;genaSfHYw=7BLjI51GTr3(^iBH`w;1lX z%F-G7+5Z|)hz#QmcPLflO=CRU~gU-eZ+lm0Xtd1+gUQV zhqAm$d9KraUdzmdW&VMaa0-9I?P^Eb`PMHhlt$rl@k17M1<#XxKEbwL^$*a~H%)YQHuWBLo++?E~Ag%P-{qs41IShlK)3#DW=Y~jhL|epF1)sfZ zG>U&50?fSK+85)>OBJWO$Gn`lk^`^%)S7zGe1%|@veUUd#_7eyr+@}Adv{56O=aD0 z4QCQ-)<4vQ3^k{1+IzqIKCmCnCck&1{%fsKSn+fR0;|9Pd!WEeJRvWk123g!i~Vp< z{^1gQtJh?kM7_E~m2#7z1ovG^vVPXm85~L|TVBt?hUf}-Im?dM{B^pW(KIEFdM)Q6 z{O0zHte>lwjlWum)H%Yfh#)XdLt8KiXD%=2e2s5y+j;*=tF2{FQ?$rjFYR#x+bfMt z!*{zuO*Z+SOWa)?#FV=U4)~*ZWO}D<{zK&o&%U>x@}(0#O%OtB0MTL!-QL=l^M#O$OK1>FGZelb!d?^!$NA-=x2&sLqgZIsSCF*W_>qTezT(Uq)6k*yI;?F`YAQ@(&|b- z(F|vdMgh%(q03Gb4OBAu-q;_>ZRz+bAUIL0h}|X859E%orcJ(j8Yp# zpG=%!Y{mIDuS)1~e8D~$G`*rdwk-B^=HZ91?}0gc-Fxh(-h2-I+|hFm)=hu(z(z^3 zGGi%2P84wEN}EDh)gPB;B>aiKjdgk0Hvs8jIE zNKDGNxl8|jxTAtWcg-*&2}HMhDyfzNfjbnN7CH>Cnw6KH(v6Gr9P>RUQNK`^)ShT$ zDxSPnr-4Y+We`D4{H@S_SRyyw%4hzu7h1^fY%DqN$sOiqO=f=;foZJk(mrLGI0!z~ ztssu+x1f-U)zcGOs+-F0%*U_ae0GzHXct}EGkoVHRA(3*Ix|37P81OnH^0DJAfBVAJl&ZxxUe(krHEz-#j&6DWD-Ln5H-rlIvYdevbSW2vTcd>)~j> z&|}apo%VBdCB@%~zQ^buFCpoY@`6EDe`ClveL{T5Fg^ zKDqIQCiMYjPRZZJ?8(af@+jf2gT&{Sj<$Ann3|4t!PTv$0%SWo!ubR>W#@%I# zCpYS3iF$-$?ARda!rZ9=5mI3oTK0|ZtoEY`kSftnI(_X66;1KuS9%-XNraglL%c=L z5;NSGppWi*>D=s%Ef)jh>bs(?yW=qmO0pyFHWG#E&I)vKknh`7sP3! z#y{tEY^g*K|0Jy%kv?c|E%0pu4Z?EO(d7}gK{>cgZp=BBKWYTfm zqXUIkQYUKtdy$JGX0zJ5xFnG?|DVq5+jEQPYb{YsGNuwUT5NZ&%l-sZ&=*oP-A(p* zg1O|%5_Y0BHP`@pFiF9wBJhPo%)5rELxwZk>JuHk7!`Qk+>(%BcBmx;c zel#syVC4j}BC7k+HxGwH8FF@|=&Z2jq!Md^==*wt*C=v4?pc>dmL`weBhak;_VAlc z_^x(bsP&$Cf%WB$dWWw=-cXU-t8ukg-60d#7+=5p_1f`f-3}TrzyBM%Z8;i#zy5N<*ON0{>!r-sLgH_{(J%Bkv2AI>ubdBLJU@P5@rs&(^fz}Hk`8K&aREty}e++mXl)-d4diTBO; z>{1>~DTpAWW_MXWw_Gs)(Awh?y&AaZTvu^wPJ|Q@qX&C6$0!pObB9Na&#FJR$7?0L zny2P`*0Ut}@w?wYMSm`$j9GZ$26%dO)wO2bSk3iOR1>k357z=tZ=bSAuydLj(DgJ4GE`3KYbU_7}d7tQymQBDyi%Agctb zEu?BrHopJ0M*b|m-}XAqYB;NbV@p2*V}MoYErP5MCzy%p#jmPXO1%6qKhYbu zmcHu^>MR+`Qx0?!^CYf#JS#1EYN_!kx#MccN{wWH+apc)TtD%esTs95w}qc(nxvM9 z;}dSg<+Jw%$3+X+1gH(LMk0@1x)U z0Yw6vYxgCUd z44>yH^wrT4(Y;6c^2C602UyYc_dB{cOW!Lq*|KJz`>N|2N3;RFF=9_&j|S7_l5F70 zGund7KwelF|J+|B91 zeQG**aV+#^t<5C2{K6_jD6<+{TA_ZCg;?bX|BINU7a!h7^s8~T(29+P6m=A1X9g4) zPw!Z8nwOLurV`EU+Qt=}x5d0X8gB;+GPbkIurn(`v;|%}2E`-1S!b7e&jGB>pt$0G zjCDn+=MJAEGB=oIE>7axm+qu*PWU^uFZ9#D^ZnBlMc3-GJZt~eBHhp zQN4|n6`<*B3!snrk_1rHDMyhx4#c}<-DZ>vX&G(r%$8eD@nuvqy=uiPMwLFKUTgGg z#iplS>!yNbJHaR6N>|H3p3G8rMew(!`5SQ4G2m5gf)%eyy<&Vw0rRQkSyGn-G4PKu zim-j+_OprbV=2D&Nk|3s-P~9i)1!x?bNb?W?o`8^w{Fc}+LgYDashDy>4^`~m*+R_ zpJ5)6udB@jhV!qKRj{GQ}6j9Iln|}qtwSj&VZ%I9y zOVs(^kWF)yIpm1$kDY4|@1p*JdZi|6K!FLo#Gzalg-q)SL4?gPyb$R?vOf8KOP5hcNZQ*j0Ii^3V+;j!nQNtYTdq4LMp#)U-u@4j;0(q7-c&C0MY}~tQ9#pdV6y)>M z4f*4;kf?MKQIy^Vq=txq z1PMezdJ_~75Ri_v2!sxy7wNqODG5b72`B^zaX;>LviE=Oz23FHF}^XrgZF?laZH}s z?s8qfS(UxDKsTjS_bVU-u)?v!!mZJErF)9pMfImQjYb*Av>hY9Jv+aBY+h3qXpzN- zrqRn?goS~*Tp)!TiKUz=B9CjY&-EQ+647TxJ=EtSBrgA<;3t`msBz)Z%eb2K)h!F3 z#~sqzn9YToKlL&mn@gnWF7*t4PNfien|Md$WBTt)#tsK_nrE>=>TvZ@X$a{uS)jQg zy~9Qr--WTVHiTY8S)g;pwiP;!W-$g4bKEz+hOKvcTc^B1ILXBXQ4;n-l%Pz?Dfx37 z7|+;3SmLJCae40KmvN8e`Git26ip@dMf(irdlfHx_2z8-U2WMwynxxi5zi5cV^lt{ z`eqVPcALH~ukr2EHxJ&Ia6Y1^&_5TfQ+BtQWJ0vghDDNu%3&$@t0r^b?ppK(^g7g; ziD-!QIy}F`@`&?!_xWH$N=5J9TPz2rt%h$9EM#tSKPGk`)W6hH3~TR`vevgwo?V0e_W$j0tvbGs!NNTNA-75)S>%ACuzYJPw!T==vcu<% zKhP!uWdOM9MPw*R2xrSMYt`oWa^KpZOtYd(Is)=hGrGc$VyGig;eGCI*8k`}d%DOD zsGOMIwa^9e&BKn2rcw2gb}}dY zF8)=9Z{f!6xVH#`z3+OpzDZK`lS9Bmp;x&EmasExb8^+}WEMHrxp`)USBbL0rGIB98p{;P@~5r`J0={ z;cLhT1NY+LqSCFx(&9_s%gQ>hX1B(kdmk#wdR^hL`SRyE6YgM(tT>BB5?cuF^Rz`U z(Y@2cH?(qLFmFRpu^xp_I!3!UK2xjYemULJ_+2U@eCQBjc ziSgRT{rxptW)mw-krQenG=lH*Vvj;tDV%O0#~Q8$XoEC^Uc>$H2FMP>85Lc;Tr^S* z$pSOIKW0DX=|gm^cR;#&Z^}nfr;G5ckS$!_qm>5zv`wn`oi$@3bX=nmoC2L z6rlaR$O}vFly^OF;}<6|cIQKVJ@N}JuL-?ny~dYd#txgWIp3$^$os+8U{oXBt>cj{ zX@Fq6Z4B@oQY?ql?6Y+QVhw< zYCu;L;O!8TeOvedaerEO`lUSR_HU;1YDmd~#6>7Xdqd1PBGe?Qub_1a`RF#&l-spa zJ^BQJ&snU0C>-Ni=i!|AtTyBYBDA9+mk8C-S2b`uJo)($J^q`y&b^2mL(5xo^MLC@ zWHX_TSqc**1(zcJEG1Fmf4)&;#L*NIE+u2!HdCez5B-&B%AP>FzYnO$Kotj6N^?}4 zZv7q%bkdT21$r7}4p%vQPgWzzWOaa~8C-x*xMIXDXT)S-mRhgMh z_QjYO*`FJEFK-znbe0$-znRHR%*FSOxab$c{!lzZPcBW7$8We@*YjbYnlcNmqJF1~ zer$ieli@`ksrtkT;M#Qc#`n)ZIebXO0#V6~kTNBh*Gf-7lIXz!D2y=H5 zQX$KWqEEzeW`Yz{Pa0PR@;(|J#@u2#o?c>_H3SL*29{WKb)LqTMew_y1YT48cg1f- zs3|0RoPO?GE&Tg=1`j8#A1|&jrJ*uxn%jR%;SD6(UaS5n1plSe*#xvGQFtTAc4xwHhkXa?rB?zZ30q zr)mv*)Aw%M&$pRI0yD^-5n|1jX*0KMZoWYg5x252X7%GvB8HeMqz^M+e)9=0VlV&T zI z^h@d>?|us8qaF`+Bv|yU91MR-vXLaHbPQiM-xx@#GQeI=)HC)FoYMS5ff?=n z%0k;T)GZ(v^eT2PAgJ-NAx8DbE%wr&=kB%@I&nU>ESs2?4s%q66Qr0Z`-eiasxi~- zNCWHAR2b#YO1YLlWJ{m-y7ZsQox6~+`(XRFg7gc1`*kIlKB=F`HP9kN@M9}6W_BF#VTDn zu_%|qgWc3G5jpbjv>$7Rv+8<}@CAw-suHX6YBHAltyOi?ZO47*ASQvTPp8VOrTDb$ zs*=aO8)t>WTspqi3g1#*@&p>K#h0HPmf8#oq=4DMj&iZK%)WcAuvbkSapV^mLi3w0NLzD-KF@nX5siK!?s_vwSA3 z57Y+eo$b#SPkm3+wfINFg~6gt)~7V^r}cyjn8S4SxNKMN5@M##IOmhPaR+O#P3A3; zSpcU3c~NWxBUP5x(LGeK$v-uQQFb|@wm30iZ06bzB*J|eIUlCm5@gHDH&3jS`seO) z+iLJ$*J7NlN_(K~uy{Mdfeq@^%NMA6=zNyoyBKQGRf8m4cfDOYmB}`SqH&5)+}Bb{ zx8jQ8dUmg(q4$kl@Z5{16beVHmz#5|-`=(P*}X^=bPgzUb$}}&i`&b~k%~K@gHy>Z z?T|-f&lBwk!))5Mmqepj6N6_Z>Eq7L4^aoGH-qvl@Fe6+N%-#cSgV6F}}-+HuFJ_&|PatZ0_nUb2!NA0x)jSP8iAG zpTO2uvF_Io!OaB*b!bnBCaQ8l9LAw@KDdzOF2J*9rg^e&^Yf!(c>I zkYM$=^SG~p&b`UC+L|d@NQz~l=IM6)s zmx#F6w%v%3$1bKu=ER@_Ef?RCl4vJ$S?4gP_cStV3ni;|yRYIYdPJ zBAZ;9Z#sB;k)@zT)IK}WK*PGOw%%OkQHf*(zeq)-5!d73mG@xX_1uh*V6ZF+xH?GI z_@8Z%C)k$G45+WwTtId`Qo11BhvMij4)7=$GR(0i<3ho;eZ@+$teaIl-Fct5- zybyBAC)ZXYaM{utwyUZfspLL*#7yNn@K)tPqN?OQ_{W6NPj;XmF{U#UkJe_ciU!%h z<<4S2QX4@E<0NAOYoP2VMvfz%c@QGA((o?x{sz*8Qupw^^atAew;)m16+XXVj8!<) zAoc+Dox96f)Ed}kr<|iq5QG4`<7_-K0~c^ue237^i~F{M8$Jg@#I@o!-YU;lUaVnKo0$3L&5Q!}}2~ zaYyfdBgeCOF6$R6c-1Uw#1z!a5R~*c5D}i|78)HnSCi+s!b@2*sA%yQscUFbl)?Unqb2Pt3*(GPTVWr zA|m}^)LBN59PD6O?5HyfPI*=T<&B#X zJu(Qp;Rt>KVx$wi_L2LEP$hmsK{2hmJ6)QM7<4sfaa9X?^OJmp{*?m}DUs`6WJ_8!C=AGxZZ`Uauyt%9DBT+JYxLj=Cp=s z3MjkjsJ2sH;=Fk^XCR;43b8~Wj@!wV9`QWabKmb+D5jO;9Ox$)k#@!h97joExcFXc zl|%8fg6dpc<6cDCRDvI(45s=N|Kmw?J-2dwQ(ctH3UmHPDG0?=!R}0ZlND#L9`{qd zpg~g$QSRZ+Q~E(E?a@-7EXFT2?yf&;GWWF6{x#NfbN2=g%SB`LuRecN??hLRoUpid zYU=e;gkajbNC~eVdS;&f3y?Vb1Ry z_r&hl+k^(3GLx+EN8!7_;=`5sdE~b;nHun@!;^w+?-xGZnQLoaO4U8H^!H0;X&qg1 zI-}}TwSrKOb*cj|ZjTavb}oi2a_zM^|Dm8JDHGj`FczB_mT`v(vmr=VS92-VEhG95 zkQewW(3JTF)tca&gZ_oBEwgMuH}BF4(Ha~hHddbA_K29NuJPS3WdQPg!?|`px;_1! zo$`L0a>emosuqo+{Gpv^^~SqFCR^Z&mhLXRcoLS85A|M643|Fd{?HwAAJ=DaZ|X$9 zR`|K4_Nh|mc^~G=)ReuDw=pLvt;pH)2Uuj6Aro=g?AzG#xQ`sYL7pXsK2?dU44FUS z)N~+{<_@bwTfKv}Uw`&gc7!qL&0~$C9s8>yxcKO-s-sRY8~jxZF?(s|SLAke3-vHI zIv<^;D^Z)2m#A46@5mZ?^F^rMJ&In5d>9f?y4nkHZe=m~EK<9wG(1o8g5W2J+G_#N zHr6)px$7Mz3STT+aS>&e?|i5GuwAcblkxI3l*)zS#6J}OlRASHXS?C7NGE~`4cbDh zPyUv&Y@x&O-7}<5ot>xKG$dBhJ_eSL8|G~=i*Vb(d%Q1GVX^GQQGl#FT);{9qCb~9pk1CIRM6! z!BQ6gh5)l~piH&gWg_C?I0V3qdQL2C9H6>&x-#mbBt+jm)sYv%D8wOb){Bj~*@B&a z?nMJxXG_e26d|)7NAwwHH2Xu*Zo2ffNyVSe=HcSAMyl;DX=&-{K^-<>^lIcss#Xt* zSp*%z>F+PnHCam&3L?MGxHnu1$y>Blni#R&NZc@qc9k+m;XM^nfpS5Te zF~evaXPU&aeQ2V%dn_=c;CW+L>- znt|$}g5_|SEr%K>4*E?te|gZ)Xj1V^d(qqQ{DaYcr?uY4wmu5lqLTEoIu}-^)8c1B zaB=mQLQ9BMmgCd5O;C<`SlY?t>e^nX^7Apu=Ve#KWJa{VsEVI=bo^}kqh-#Pzh&KG z1dR9d`a{vz2d+V@BSxyfAeMFkL2c5<;}t1QqO;9eG6+Nr$I1n(U6YA>oA1U?(O8{$ z1r=+A!|-X}gyh%ybKiC3Uht~75UF`Y4_Y34T?=e(rxw;tL-+#d{Nq z$Oz=u`L>b;tAVtPyp$=hvo5z%O@hUhRSF^2*aVJaeR$y}cn2A8`%A_}fT#*|E>@lX zIlNn+egRyBqiu<0o-%NoJj_T21oJ`CW-+?o_OOV-XtI948a(OhX4E3YcRHjx5I0=8WnpKRl{NC+_s7CXb>A zy(ls+NEbMrE-g9SQfaAR>KbN(1?}k)z3s78{PjzxNP0tPu^Xof^#j*kPiHnutHAfD z;`XIv?I>y8k`R>Xy6t~G7T$eMXu;3gNWK*&Z@G$nNT!1!9g)Ih4Dt6LihEOU0e)^{JlW*&Sv6sc99l*R+>(9*q|&0- zDL$`v*jH@-#R4e>IsSM4nc1y`EtF{j0s?;xcnsa|05a0~o<9^)SO3#E?ACP3M{TtJ zF`V2}_vPs`dJAgurCso`xmHLjf1{Q^=YRcaI4=ErZ2$gl|6Xr@PtyOB_Cmwrd01JK zGq!qawf0o>yO*!4nh>c=Z~JHB!XsqpkH%$4S+$-OEA@S8+6;i8t@}TAcdrfq!=Ew< zV4VLS{*}M}?$Q5V%(7z33cSBU3kDT+Zdnv z!_9~xc#%U%Vi_R|tNF~36=)Zwl@}K5#t%KMuc`IZxeD{*;_1tzxuUoeAZ+?%OH%51 zh*(ktXc}6c3xpinGJ##d>|1Gw?iOyCr4GS4R`z$@o-9y^B4hUb65FjaZPE|>BbIAS zpVFjKP>`}fqX5qy2n%V@(u*Y8v7oDf*cs0m+~UGSMRe=$d|i_xyPH2=-7Hitr&!Xs z#JO|r;#Ll&lv=8f&MQHRV`}e{mqoI&kW#FBdOgS0>5^M?xoR&B0Ph(O*kw3|e4QZC z70*DrNlYnmO*TB$fP?VQv%b1ad-a|KrIyUO%G-3fIhtov4rD%e^zk{+`%#!+BX;UW zH0-gEYaPb)9Qsa!#EAVSe_7C$SaL=FyqiVSheeG`DEwIs*X}21fRo*Lu`-8v+ZE&U zS%OyNvaNVLQ>WZHxG_GzHjaE{%LF7mD)*oSTI5kGLStQ~bHvD=)-F`{=yf+3Ip zF0x0R5<47EG6bYT(kLQr4*WTx560A*b*V`e=UZ7jndn`*h^{UX;n_+RPBa&}#@ZvS zNjNTwio0LLeq0Zb_WX842$mfJRXy8(C^(vNG>TcQMCb04m7Q!@m>f{sO3TbD4@{;Z zFKpE(PtkH4R&|>WNORxm`;_0y2`)R4Iz|!Gmklw0D3(maK^&ylXBADxrCUMt_~Cbo z?gE@DZ<_QNlcq9|`QshRWqxjGi_Mx^uO>-?_ReZ$y)JJ?$1lWkPkf6fBC_QYfEJS_ z1};?-9~Uu7k^#)z;-hH~iJD}Bli5!E2j)a~?-w!Ve9O?Q%aWE9<&Wx5%&kbuPJAR^Q3%t{{B%kU#%WV0Cu1kS zZDdT-wIWvp2ee6HxlF1nQ^*=dyN2(Y{M}sXc7HcTIT4(oCe-UCdskENDt!ei($$F4&tqopR<_1nINp==Mpyj$v?bb^3==} znAei4$knK=!w_P04)NvIpeBOS_9I)#7Ev1E!UBo{gjsc0BWuk_8ncje8h*`z3k|qAwFZzg5 zTUaGMgiBVoH|;`WMWR{O)5J~QvoFVtM{i>Gu2?KqL%R$GHcC!yNznM^o=DO)oNaKB zXia)sCV%ymL%4yoV(e|4l)ncZM?=)%n$Ei}A(tao2jjqPt%ukFgg!qvG5xO~3fXBx zg-4fMJVaupB4m`(&C+j}8~UEN>P)=Ug-sBpJS}DPGbR<2UgM`bQ+>1MdJYTmrtu`( zB_53?(85r~x%ZySES&YL@Pa7Q>mP@AkN76fG+`RX_0w>P{4Kw1 z&FSR#hT@~4^TJd&55Ir?=%F|i6?OINUsVvr|Lz~t1US&EOi(@|caQ~vgE4>d^^QMh zo7^!Q6tNA)F`eDEezGoGSU#$CIqZMxdi?J=5Xb%(PxR7329@j0&F!=z@7bN~-?!rL zQWq(8zz*8EQ=&Na(Id#*@!xzLzZNk4isCrF9fq21(HK3p8=uzT&$NWTdB3>}Y_5tR zAc5-#61YSlflKybD~4)>jDVjF&+N6MSqPkO)a3DnZ6}_gI9zNwKsgrstlW?glbGce zDNL)}K41z{)f074DrDM@J(aQ~aUo`h0ANxWTPrI#jm&E;KH+L0gi!FW-Y4apwg%4m zc^+3~x_>2i{SDzYWPuPqSU;X@K6(}ngz#b3KnQ;!MSxUQctC%Ah0J}Hf_RRgTK9rE zw*v|?`Fz)JwlkX*81oH|Z+B8oo^{vw39$<11UN;>U#MGTj=jf%a;TUfGsDHF7CVi$ zK%8T;b6q1{kn+^h?Dw1RTf=THH%f;OYieID5nn3S<>l`FSL4WC)5F%u=Nn94>is{28qHb z4Tz5kl-R6LUnKqdG?QQ924{nM-l6h`zJX!U>uTCJ=VyOZ2?x)m-}+vTJmmxu1%?J{ zGOaB5*jeXL4oL91e3(eAR*3zf_)oUIxZg}Oi-%gk+a%aMj!gtTT+FK&cK=G*Fa3H& zOXaMGVdo!s&E1OjxyB`$lYP!mkkV#+*_M(hg)v6`u(>-_6U&>=uGV) z2>MPBe-6z~)FpDshVB#L>r+{?!RrX%VG@5E({zBUqPz>L4mv#qpC$eV(=df&;@kIV zhQG)R)aDv|(5!O5>#Zo@lxR;I@g-qr`2BFLSM-Vml>M(5g7i1XO8J{(i2*s5^!k6A zAjI{Sgq20s7AFWDbap#vIIAi&E3}C+w@ZBe*9J)m@^$^WuzBV+#gW6&%BFX^_j_aO zoYm5n5RT9p0qpShB!2&>BU3&=fM=_rCCautr6IOE3F->rs9M#5G9+`juZbmE-evHz zEcG1Z4)#mzoF4l_@sIBS{>P579gth`2D5@4vt})qC8B#enW9@5)ueD`z7PO|#f^@4 z4fH)U>6Q1d(%e~nuRHhIE+NhUCI_tjrO!aA107G;>p`FlJCT>xK}rP9D3T#lq)+3Z zsdi1;o(9arW4rU!G;5@&fYO&wxBX$yH1izugImc?#3)IZI1(OC4ut?k(FPgv!q!s=tcbm-`q0rOX;~sqYkwsXcb7g|R$RX&AE>5M5HgM!Q-v?5~!>n)IM% za!~|gG;nW;)lkug^GQWc)V0h1J7Tf%|6VKx1WWuNB>c=cm#O6zQd3 z=~g~8==@5zW9suH?1kaL&7m8xa#h>25)iWsm>GCLVL`RFrHQapnsVYZHOEb}!zv;< ztf27KY{eKV9qN&!P9fd^#;{=vstNAcI{d4*Vojz3m^6b86|rOmzF0uF&Xi=elIL;R z;bO#vx4p+X;2DWFGQ;#Qhz1tYnV`W@tA2)^aCWs>=-Mvd!J?|@KAG7ku2*WW@N)E5 zv=-l2o(LZdWU89OnRX;qg+GQeyXGvcb^X@OSMl;l>{id;Wv{hsZ=Alt^xl(8Eo$G| z^swm22I4hPX3gCbfUPKmXbm%VNI0hq5Q@n_LG zw_zCQ>PFC&3DhtXQ4&hi<;q{^ComUn=&_}kNN+I0_}kdo?Y-Hu&snP`|i%fWSey`QWg``G47uwOEkIAr_T z`Mn3 zZct%?z7w)v+GRLsB*}Mw=`(YVGQ%bMYf|0Y@$tLBZJvo>L7fJ2YP#2{85APgl?v7y z-kIL+8cJU^bddfKwBF?|pE&0o!t3lHb@disVvL2U-JGGrFM8bK4%^aVhyZgF@M0CO z9@O3mS5cHau_tSUSs34D5zV^wfezk|)fuP*)pz+}dH@Z{y9K^)Z$7< z;&shoS9hyo{H2F3r1qZHZ`shFYQuSmNz2G60VeWQxGHMYS7d3t7?v{~^#+>5yK4=gl^UZXizG4H5p5G=E=ZvGorB)Ioxkklq_!rOemay44 zF99-DiKEW(Wg6d>2#`o+fVIiOp2;-2)A5ELE+D>Ehi`(ex45E%eXsXr8T#^ZKzKht zc2Krwot!`jz=9(@eyi);A!sKALUaC5^xm@stm66)TeecoB2EOF_F1Pw%KY$ZVm>yxGdrg_o6CEd{b()CDow?br?`a z9%eE2`Q|PL>oZqWp2SUsir>ap+@qRGO8B(o5VEz%0I(^tI9(Q5)%Xb1oi!G|O%|ZC zGPkr06y`IgsY<_S)^e^(^1Dnaog?c#{n#&8=`<8r&;7?AumBK3zNNS6^nmC?Nsm47 zkvq9#PGKeuMzDPwJ%`ZdmyVQ_W&X9TwirsCvoDG}mc}DKGN!t96=PoyW<4f5VIEJOQgpew=)|ZQ+g}DtBr2#i%m{czH{Xe zk&Kr#C}iQi-g?2?#vX5bs7FW%R|K=Ur0pWTmNG<4(Wr*8U$%5^DNOvIzG-eGbM`z0J=A{CGlHLjg}i#kQ&&fc1*$>+j; z-f`akgkB%p%EcZ{!d3j`+7m_e1&|8Ag8SGwu7_9){@yZN$`{YCz_%R3bNUTG^qvLpdwN)g>7G-=7jE5&l-0MZNo2e(A3*mh<2LC0518-<9m z?hC=^6LeX{OlNetR3rJZrw@a^Bltj)#3*Y{Z1rJ6Axyt-{9@9lRMan&`!&)=NC)HR z7MF#4pW-vFM1&pd-I7aG?;4cy2+Sr>9=-!!)N7Y9fV<*iWrq%QQ2}$&oQ>~n{B;}A zX7u4=b#(FvtQ0E~7S207c!?)?n{=$zHiziml$YvJo_o8l<%{M77}ibD z><%3CBH%Vdr+YVkZ>&s}75rc?Ip-Kt`T4rw68|-6sfH8P45ka8KWs)1|Wf{RSUFpLoThDNe*V zh3T|%=-!)|er9T=gXvHZN6-j}hR_qcgNpFE)pTna^4dUePdncm`qkpD*9GNWhY0hg z=TFU|3!YQdoD(U7pJKr??mZ_z!^@gz382Lej7fS9QTenz`RKNk?!o4bc|`-h$-XA} zP!>h~s|G{x{o&8NPgdi-yg@x1(u>Tba}aNDC$Dl>!l1M7#n?`W_Z64&a<7&4r5Y1G z71_?4&wE>Ml}aIE5me<%6P{&o>zwZ#afGg*4Fsi3NgqzpJOZw5-fPSlY_{ZWn}J|z zu|q^np;bqlED2Jb$||%0ifO}9j2{MnTDgByKbrBBNnN%sp|g>*Zc)6ppIO~Y^dr;m z5kLZAe&`F+_G6ZhtW^xhgjznBG}PB-P7NDXH~XH7m>0K~zi;7LIm3#CKASie`C&D- z9h9v>KrT&oradqr%ZyrAugw))Y+CR<01OS^!gbCxfrwI6qcZ0% z-pU2nS_iGv;$;=-ZfhEr8;HIUXLiYbWsivrz==4ri?;x+P1n?zn(j$>xX5T4(@u1> zgUo;_-nw*Dk1Fd5N>e^1Oi}OrO^Q|XZyz0gcp6rm*n0!s>x`7}Z8b~(WkyyRDdSgh zeZPOxa4f8j>^Mc;JGCl#aWC=i(xhQj76$~)xj@t&au;vrm!4i4NlLzxsc*`c%Jrg90Cnh?%Zl z7pPk7hNu`5jd7M4;EqWDr84C`&54|_eFzeI+fw*Pn^4t-0krDm;+(RBDgtpp-dbD!*`sExY8&^5f^rY~>rA%4`}O5% zi^fme_6FMXc?~bt)GMySd*Q85=(9etOgw9mYf=Ylw+F1}($`ARY7>wqysCON~)+x_L3STibGQH6<(6fY=Q{4}fjn93RDeSLOyvslV zR~SwfCFw!voT>=mD7CwR?(WjlG*pcj^ys?QTGP{RvD9+Ry$!wr*E>u`r&-6NN#_WQSi??3 zsw{4oAi=Sf+M1fEpO07oj>xxzC;sNMmMlpte8hD(SF}2bzILRn>512}0f3w95T2W_ z$@LWc*!2c0dZ1i!ufLHxCT3abcp4`+_Czp|Z-6fLixky!QOacXj=z5a983V7Qi%3F-J^qT4L@;k;3PkOs3I^WamC{N|x$y2rWtbq# z``e~%WICejsRntNUt&Tjo@&EHr{kn~zAULQdp<<7_=P$5lfxjvG;WWuM$Lz;LAs1ZTgka$M4J;*~fX9w;gArbq)!ir@I03>9>@4 zTdYnjoTu0z$I2}Y&{#DoVRt}SjJBDqPr$3FSI*Zx%@zz|Lhm}DIE)49)|J4sQp?h| z%zI%8KuiB@A*2X?cbw#TlJsL-{44LPea(G~Qg_ewR~}B0F|ClBf}S_?uN-kIHVT-- z@113nnDDi@WFZ11nPqeh%^`QXYCtq84KpXo>6>PpmCBZfmFb z66ko$oRnYwZ~-@sQ)fxLRQeCzpuEDhzx18*^2cW*Khm5xb4U=PzJJj?452|#{!p}e zSYasTdN@7u-6v?UPFJn^<+8h!l-K_IyBk*VZA=(LYA#R+rqPJBl)(??#JGcIP0aUw3t& zYLmApB@({f+g=`kD(*!-gH*x15vdWk z9Ddx&pE=_u6m}xR!HnB>lOSPOh{1?Vxov+KM0;1tYz6M@hARE?+563FW7U>u1f7Qx zA6OSn0DWLwK=R(0X%pL)5}WW7jj#}tWr!9sp?S(Yb8|?l72yhf_qVtw>O$rkNAqq@ z>DJi1-eTz&`sQ9GDkS2vW*JZu%f3IR$$1p>5I`3 z<%p`?ocevMpLAqPAV$ z{RQ2smM^ZT@w=}=|400VRwdh+!ov@Q#rQp-Si&zn9*b)5i}b7D;_Rs4xs%yxb)s}=}&_KJ6?U*nfK=r)Pv!<`0#RnU!*IsJ-HmR1Xl+CSzx2af(8++Bn18dyHJa32J4ReGQ2cL zj5K-5T2u1sq%g~a6=ri;Q}c)Info5*^Cd5gJGjEHN5-Lze17b=nWDcFJ~`SOThb_{ z{(NnSzELlyHpZ&7y(?AhL%&m|0#8`H%O%6}pM^8ZWnG~TJBAnufK%;!szww)?X>95 zwht%)%0j-7+`yWvP+45ER*a%rue;X!&l}yI0qEogbar;26ZgD*cy=7z%HkTa9h~ z{3Zwqjo_y=nETy$uJX*MU~m9#i&mZ!NRJ%CMv#wtm(xf%f&_^Tp*0c2K+h<<%GTY} zp8Q&NR#xDYONj=uRFih7$ehYyF8of@k^Vqul9JUucM9x;j58vVas9f1EKTxW1mXUk zGJmCst$<27Q9X~EEzi+ieoJ<5WgbC0M{Hf&cIW4Y+)XAP@)WqL@C_fj)3y1;W=5vg!uNYz|LSY|b;X z`7P=nj>mnrTTJ|%>|D?^$6(i5KWwQRI!?`nHoXdP`F`!SVk#ry%tQWCAabKz0+ zri5~J#py++9>A>DkXi49o4?n8H$)q4dAT0lQmwmdU6#0>)S3S=Vy43Ue9dShk3aIx zxSH=$hI=~#pXGAW6}u3+ss}!dQDOP+x~h?}_fzUJCf(B8v$bvbJ~2^XR-l^=Ze2@2 zSIDOL=6B(Geb<8T?XJ=IytSj6ia>snIM+IK{tX~naUUmf;sGY~8#El(##=KnlQXF^|=X=qFb$AZOOT#AJeyApQZG~zr`d6FG!9zIcHnB zy1tOH*jLw{-|1Y{j~IB{7cNPEap;9Y%+oQ_3!)4ZtE=V@j#1Pc*?oShcstsSnO;wv z>kKns>j0)+rB>s=i5zU94QkKgc}`Furr<8FCHbTP@5l|+s;O{}E%qK_6iwxa%GZW2 z_#u?ks`uL=7xm6*2V|cL02YG6P8eB|s0CO5I_$8_#Ju(D#F|v40X#ak+T3)%TeJ3k zkD458Mx3)aLps`t0(jdhMPTh)TPLF=YzOBozKJ?S8>V;b8 zY1`hUpd?QH0`msZ{eXGF?V-zzEWg6)l!K3bX&5W&p5D0fuJI5`L(e|+D%k6-t)z=U zB{VMkEVvxu1hITlg_ zg(dbstgWvlc%~rT+`USy+}bx8Z;#>TRu3RT#_-;BwhJD%srz4yR^uAt_Qy4LOS1lg z*tVPGotNE*IoA_h8e+nDEdMes%~y=>>aNOF%rM`j>%<32B@-10rvNyMoy-99TNW=| zg$2!ZIz0=fZv?^sn|;(Z*7_N~`4pNjPLZu#$oSG0M{o?9mKY+?IZRs^t`u3;q=kzn zDh@sbs%!c(fjROw8Z3JqGUeo0uf`@NM40Xds&-^mrbI5Cg+4n=A>9pdX*er;7Y+4y z7tL~xB45L-P2E|O7oYg3ZMiaZj)I%l0n&Egbmk=89B>=$>5R$wLU+nQ&DP zbmu46SbCa+J&+cp{mwqJu?R#9Tm0A4v1=c25b-VB8d>piq2|y%5&5&Fk&;xZg<~7l>A@^2KoZ7G zx(;}A5Ins;GutR=_#v62F>d@tqCT-O&Llx6xp_GmK-m1TN(}Ct$8rTJZEVZ;Mta!e7d|+Y7!(=YDAiW&$(d~Vfx=k6|-XwAudzKU=Lb97~0@T?wlfOgD z!eg3L3S0^OYL$7Twyvho7ZK|T*RMZ7R{sF~{z)_0ZWh!FtWar1b*WB^SLu07EM~CE z#ZI=lO^eAvl8RT?bKr4GY-v*Ns~>q6L)&On>fFzpKBAr>yFv!g8CnRwiiPtHQInT{Er&y*ib zedw-Pp}8^#-ZQ#4D+xz`c}nyjmCaHPB%~VucnuB zhvl25jj`XL75dRyggO81`LjF!(dP|%1M9&FyaDlBXdnobR^z{}$_n&F8Qfb_eG259 z4F%ed48N_FSi=p8t`0~H(dekt!tr)KKC-NIVOOl~lVM%A(T%zEpzgUhevq5%?mulY zKzh{)<%DaGkR{-16(hel070ywcKQRta!@(kx<`nY6+d8cz|7SYF;Gz%=eqy!^Q(@} zC+QJBV3|Uy5kwu5HLgtHe#<=fS=#=|74dnMlZuKT%C^){-ovs2;@c&~`4-D>JaW_b zJ%03boi0Nvj_W?}UWwoP9Cr&D9i$M{OO_y}7QvrQls!xwhaKsR`JD0Vm#yyPRj~RO z7zsa%8W>I5?@u%pJ%8~fre(W|Fl5L-?2w0!SopuFd(UV%zxQ8Q5|M(4-dhk7HEN;_ z(TPY!w22_f7!%PZF=i5i=s^$!5xtJynJA+~^gik!f+#b}7>vntf6w#god5T~)-UHg zZ_e|AWi4yi_r3SNuD!48Q@Ar0HIicNb|3}g2aa}zaZ^vNePdqid@4#Vn>uqwoKar` z3l!BHdXIIf1A`{&3h>|U-K6~CJ0%6vXLuytpWCk>zNmaRT800%Llq*&=g;qfA`(%I z`^{j}$`KzyrY^J<#B2R>m-7p;IytHPm6uEV0vC!tM+Y^-4ccWVyE>4UM>W~zA-!2P zg0$wjd!4t{+YZu4dV8Et;hVwnzQh{P>?+ucjg;TCe1m!9k1bLNa4P&uGwpw9n5EE(>x?K}Wjmgb=kexsBTj)RCM=sZCBNhsE8UF? z4g!u&j?Zb|c!3`v`$4o6e*#mhoge|)oE|J8E@7bOYFVDp#T$90ne@i_(xvQg9r#R}$`kG>BuHpJ z7G({(O8{@G5FprjCV*ee@rUL~HDSLt{Oc}o5PQBtZ<36B)_9xy{PXVB$XQ4y@*48H z>OlvXAHLLOj*H~+$jooev>`t~y3)DW{%8m}s#|gGc8hg#o7~xhPMgb@BvBR z3DJQFNxZ2-+oqTF+6Yv*T7{LbS2pggO8r(}WQLb5qod0|V4c4KLy!I)04KE=q6!MF zs^4!$Zt?O;I>{dOBNPL%X8a-_v%=i+9ykit47sDuf^7s z1=lX#E@{1Zmx&(|3s|GG!b6u-+G+_I!A@12q@$3G{C2vm#tlyW&c$1lh%ezAgWasO zXVn)-==c^XYM-D0Re0U1Hq5;WbRO%qh`wlo_b)Qq`V}WFk-QS?A)U?fv?n1+Cf&x- zxKQWv^(?mW;zZn(pr0EC@MT!l6a&*i(ytFoRfndiIhCg$ac$ih4t9*x?dNMODtO#! z_|)LOSv9$lkbZ1Armo?%7;qJ;qiZBK3XLOiqzqlT>6?6JEApDqjTbZ;5Il?v*^w?k z)}%lbG#HVs`dzfmW`aj;^d66+s-&#=e8X_86l;Mpg zK)~r^*)<~!gsPiC6%&tMt}D1*R?eO%w+*xSQ3d#1=1l%pzu$8`Zn=<9b?7j2_rV4- zScjOpaMJZoaFG!czUQiVK3lFOyLOOQ>4VQhIh2%&NYqr3C%`AN_RN|2{Q(dz^p_N^ ziCe_Ogm363z2V}XM~<=5J>(WWM+@zTEHJ785;5ppSDZyevG>V!TfaNR>yXN|*QJ$S z1(x$~9mj*06N(4BR8RA8FyFLc>`4EpDT(|Js)9vrA^e^2WP}35naBgW)az?U`iZLi zIYjHf7;HXx*dwf6K9KbGGujvt`_HX^Uk|g1B0%hF$3ov$OF}(%^~N^$B2q2U(qH2h z`WQ4{zN+{F*SW)PDVWx(*Mo-Dkdp{2q%O134T^SdFSIDkG_t^tRcx@<{1qaXF-*N$ z-+4MM)95D6M7tlVA{46_)0xgb-1%M+bD2Cmf~~17QSb2%spylYg;Hv-63i z0z0jQXf(|HB#>fVv~H&{>@)#gB>WuDD4HhAjBB)3^;GYOHSf|y(#HG%OPk9dh8Uc4 zy_o~xJ6`#MbOB7rnQy4e8%|^Dr%EOvHG_usaZt?_wftf29&?weH}>i8R+{J+(3`;o z@Zx-XqZ!XS&q~4h8EitJ&>GOPOc^V$!BFA+=55I>G$&QBA5>CcN8CPiYME z&T<-%9?-AgA9l=wNtYp(&W&TF6*Jy}ShLBJ3ua-eX@$RAgeTPf@YB|3N9|L%q9eYx zD^-Wp-HtP2F%3yK$4%|(FsDmy$cD_9cg5_X!&`XCSxY{H<7$8iQVbY?66wcTO829o zv>e3g?O@%=s7r_ZiJ;`Ldv5htYM-sduLiUiQXI)TUshB6!m0<@T}ZDz&_IPy#cN)N zkMl{_Q8IU1&uGA~D@+s6z8q;X5e!mdVs{}xSZ$=UeObV_Yo*nKog#H@ZoT9;yeF@7 z=@$DT@*jjygevS^lW=xGZr5WTyO?5^*NGV%MV`6SpOkoi)fJ7YCP~u;++92xlF4f{@(>RfSE?Lo>18MU8a(2`MB_ zP@<0pPEav z5a)ltzGLF~D#zA(#uXPSrvPQC&RM=^bG{eRNNKJYau&7d1`({K&CG^S3n_DI<36r& zxZ#oegr*S_VO(sNKyzND0_z~n1@Yk)IC1+Q4IC;?u-2@7J`7wIlF1qQlnh=#^O_XG zlT6K%jF0Wg&sOpHrq}u-!hZU{zq83w$<^^h$U|||yAEA&+^mP<0+qwwX$n%b$!ao< zOkFSrgc1>%M`*MeLSAXkp=Qd4Cp~U9@s!Cd)$@^aDfK?CTc$Ic{ZP^Ue!bCfeTkew zz&t!jZ_*&lV|mQOzEIeKhBX$dW(w48GD2_(dsLQ*y~DkNyzm8^5LRt>m}!$$;Dt1Y z)Ke=jJBy|wK2bY<4^Vj#W`rbc+QnZTNCrq=brq&*L{!B$ehP$>y6STElnjt@&ty&u zo#nItm>@KPmq{R4kkn4TVqmCuAjTHf8Aiy$Rw|*W!)hhQITOO^nqy--Ne(rO;!c_K z;k=0*UYZzN|BYvv!T25(}kBO^HSRHl|1 z;c2Jd+DJ@a+ku}7k+?^nF`g8z4g-LffJCS>stsH)?V5o*C|j!myT&>k>;3FR)H%%P zuL+)Wi@qz#**4FH5Lp6Dfl|MzvfA>Sv?)wmyWNJUy%%P&{Z`9-s9?f_eW6~Tq3dB9KDQqz!N?_fSPk=V59S5_1 zF8^2gID=Ab_H6c7%LNAep1^zMKZaj9d4kd4vRXjkk~#n;+>^ygE~vE8yDG+72v>L)ev&R*7$WR~ibb4nk!o|HvDmaq%P^5fp|HZRm=A zS`PKoBP^@LPrIe`2djiaQ;s(x`RaqW5c`SnF&sz#%;h353mlB)`E18{l0}g{=GXbs zh2MOL-wxdO-;~9h=lK^-Ny-0Kxd&mv8LzRX5_2y&eEg>A8)bB|Ac3BmvFReE=^<%Q zt;*H1QyQ3s%y||?*~y5$Q2fulb}+r7`S&EEmDun3btFV9>6>6O?KAyIsC*~`V(2R9 z$zDCi-HW(xSzQF9V+uZA-pL8{UqWx}#3VH+$81dPmhm!0eU63~cvfB$yaQOAT2R=6 zu;9w^+T*7XyVEC4GBSeStT@}@)q-cpetqeR6HP|`K7RZoR$U%Cv+K&lRtSHUh!^&k zVtAG>{;+k45!|YIWlU)x5L6q22|!cy37p@+=iw%I2@F=*891JU$m$44V=`(;`sXf8 z=IPZTtLL+9cjmkwwCfQ3kx zfSf82(S<9Y6n}!)T+}5YsB-N<> ziqH$f!HTPhb}k7f>A10_Ikt?2U!h1o3NzUgsCFt~8bFtp$O?jy0B);3*N~#Ur15&) zI(1U_1+&=LN%7qbr<${$l-dJi71O)D)*-sCVTgXS2k6RbKR23#|WJ*#k`|F%%0s1&5HlM>GXcty(_x zeGXK1zl{U@tXCV7x%pKt)W733HfLmJ&WKjDdY<&OruJQr%xVdHPBJNI<;>J!=#3ND z?>{trlvDVDC@SwsI_zh1lj&lb!h>-seDsx}lJt)x;(%z(kfwir!l~nq&)!NK>|~8& zI`Zp*R!nV4QY(tj&52?}C|Y0&Qk0Z{W%vDDYpF}OHQxfjNa_(QxT)+P^6aFbK*&Kz zu5r7z9^0eH{~PV@DSwfL|IYH@@_jqzV?&DFsOANPL?bah*a-mV^?E|`)=0bc(VUGf z$wDzd?7Q`3>l;{3(FA(g!AcPhy}V0rOe?vxXq})1Oum&t8rmt*gPW#IA&~+uf!wslf%eWO@b&eB2hFs?jMhVoD=f=+(K_7MzTzb`FLi%@mYY z1X+MUV#O4q&a~JFq;InILohSkt$%L6SQa;kj`zF~^uxEh;gdwP7Kg5=F}-Y0prIQJ zuFcC}wW9FrJ1v?sG?(63gu%BLm;yDgARGy@UHnMvoH44POksn&r)tD2I`rvQ(C1+8 z)bl~l$87}a`7EL+S|<%HYzV2*k}9y^T0?2_Yv|Kv3}D(EVyeuWoWk{E!6xm8and!| zFV(Ky%V%F_w1IJwZS&ks7Nun8HdW|RJN`H|LM>vduk76bRQBW0p{trrXGdVqFKvOJ zw9%vWR-?BPyD;vijdIFMT$|w!&YUimXGBbMZmQuG$#_=+r}@yn8so$Ji7UKn$t~Z< zcdLs{6)u<0sIQjrREn5fq-$+0*03PO5b2VS?++Y<+VRr2N&Wn1l~A?QhoW&i@*cR| zYdc7=?9E;EnW#p&<)02K24nYH8LLcS?h$-0a)ntmOi!;{kt+sBt7Kd0^cp2o5zDgC zDu<^LxvIDs+c~2G<3VlyvYPr7l@H%@xVeWuoGj3Jt|J*vGONsZ;Lg}1it43u2d{+! zr=WWy9?wEIqZG~8UOo_J8`l3B`wcut(>J(87s>%B8~vfF_Veh{P_PM&Y7$a+TA1EG zhg-M6aZW$GQL>eArPa^l<#~8o!k8uVtfjy^X0XHzK=su^o@!;MBm%0(D$;pmWP8V* z58on(b@Hp|8P2P>rbfk%BEm?NNk1+U1UW$(Ncq ziK^^`cM_sa)1rmtfn|QK{l*OX9>d%$3lh2 z5ITzypFCu9YRYys`#d5bXG@yoI-EWf>RojDoGA4QU0SpNdn;ItrPc@h!!8MHuq*WN ziD89UNk>;mXU3TNRi@)JgI;!v&Im`iz$5~{zw8K6+5qzdM$n*h$N^5^p$KVfs-IK5 zdsut&rvpB=UQPr{o)xW&esz&g;k|vl+vNZk&xDPO#uJ(!U6y<;d}uSj$Eor;h!8|A zLMYcy(h=tfpC=UX{tnq&SO<6vX^*V4 zu=%{Vohmm{4ZXf&>F$gPS%W$x-LcgpX~{UKXg*(*+xk#k!gJY1R!EFTd%ZQO)^)uswqF)z^`JKaer!A zbVo6qa`@gd+oPb)LqzdqbLfwlf@>i+e*`|ug45D<3Gq2P&!2ALIZ3A8Ks+J06Y~}s zyTb6J-ar6ZwTe8_NO)H>4uLWxww*Q^;6uNdU~K-BJ97TE+;knc-#jM>5@oTNmeH2R zGt&N=E+-%lV%2eDJ#l3AEyM|tIR1Vc>dS6r>G*_y!uLYwx0h#@{Qy(UgB3b2J!F7O zM(y@H#hBpNOkq?B*N4;O_y-w}D(Z&!eg%(-4`tt&RW_;ZpXyRl0+lH_yQuztx1+mi)t zhQK_tNF0*AlAs??JPkVs&pQTnSd7>3NLU;4K#jJAQ(V%|V>=0vW$BLRk={3PCYQXl zPRchotNr_!tcI%793Eka(koH9Yre{IdOoKr%WE6sxJ~A`reYnT!`qKV1x`nGECbeb zjV|brJ@mA`ASc3@pc1Ukh&Q!5FeTdX#MUPo;=>oe2WY}Km!l2md?ZP}QXX^{F5c@} zaa>9RP~!vmk7P&|M0GQ_XfewCw`t2bIyyE_RM2SzD)X~eg#{}%LaXI){j`Zl%W$iK z)*+Wy)*eqdIlg1QHlxk#(u~`P^_tZjU|Mv~)xs*I$O*?qh_H}#Q*vxle-gvw_cs><3%!i6 zC7s#nT?Ip67K39y$_*0@+kI0e>&oV#oRMd7?M^w^4h$|n6&{It-jIB0>eLgqIv;hY zc=#lETBns(`NJF!@ih4(1UzYkUpk8+#m@wMwuRByygJQ%Vb0O@&6(1hJv}mQD+ZI^ z7T>{@Nu6dKWI(J&@O_IgykUHO<(KJrb+>(m<=5y9>nR(``)MIQw$HjJeU!GfmH(q?PMn^*0K3 zo`uMX-%DW#fq6!jC8Ic)0AL$tRn=ncnk{GMq%rWFVB*Pa(cxZUAgs>3exV!tBL?Gw zj@!$a)>$Cs;Rh~|Yn(8ZBNVVxu^Y$m0Lv*_9-gFn*S2mf@}9B#d^)*g;7vxgb2|(t zcpo#Y&d)fTHWpPJ`z}s4^Zi#mj8Dd`Gf?FqIqdf-jCW znc`=y2JQ!#w5z-}O|A+TRR9~6T&}@5(rJk?U=u1H6&Q3cC3KT6Io0n0F1bHLH>(MS zRN&KVxQ^FO-`7J;$I|COW$UI{*)cB@`^BUTEk9?*idf)$^zWI{Q4M+r=&4k+aBad>Qr2tt=!sbf+ z*{D%po=7>Yk3U`3wU7(af&JazhfkL@4|ZzLah^LTvH=*E#_A#LzanQ)42Z{hYfG&S z%GD(ho~V6NdWuG*`L3;KgInhW!w!8+#i3iJzHZ>lVm_$oGSgXL2&neh z*GUI<3L^+LJ`&ESXuzI*?6ZnAOGHF&_^V|ZU8gY-+MCbh-c_5e zIC%SooQhACP-2ucYzl!QIilw9-f_M&rm*riyTY`_I;V5k8~Au^N=f|VzcBZ~v}6O) zk5SlyDzykdePT7;@nCKa?qE8&sXnW{Ck=9h=G(s7)h(=S^aws(#O`!a)WPlp%01&9 z3;7|KSo291=Dp1Xf8EtlX~bZ3JguQ+>|oh$nAa!p@SMdY+k*40_T?mdFOl_i$u8-KRwfE=I^Z+t z$OG+EdSXn-ezOdidBEP4b|gY0cE*j%a@cTqE$`6g{jzu1lEsqmt?aK|-T@Ew5K)BR zq;7(EM+V!f0N?N)BbZXnqn^_~Mi{bNR~4>@N=k6+UQf`hakt zHggak2(LZ0HgV9Eo`6J}+E1Tiu-k&rNtFEU(CH%=)H7K;j?A(o6|-ADRu- zYDDE3Sde9b2jN5FQ3dmBR=P*k?>}pm*|f41ok|F_;dY2}^p=Vfefd!>;rvQVBT>Bb zgcDfh=jN9z&m{-B-ZZ*dt4wb|wVQ*Y#b&?)Rb~ z?%-PsGdWeZZJW&nR~iA&r(8~~eVEFcaVB*Zh<;!Sl} z)9s1442rnbrAB=3tg?m@HadsB>fsFklVua{7*1&}ho1_dPpiz@GujNNmy-bPQQSw1 zA3U&4Jv;zxpdm7Kfoawb08^#_SX_YmC&XS|dH>#XBP))3a>rQ-ZzF#i-DKZwi8*$l z=#5hJ2)ovGgpdl7=2b!oU_F#I*$P$MH4~iTml1yc`PsaC9PRuS1xGs5X+0&nONJ-n zUt8FT=O}DyqyWNZVoX6lEU#wFyI0!oiHPO7NhoaI@wv~dp{Z8d2Ca&UeCen<@%a`h zgx4UF4T2OTd`_{;K|_$@iHjPbyTe&gE8bOFyM}#=A36%SoMx=FjO^dMYFiEf4tnli zF)~OlRI3g}8mLU!@c<~r)MlLytF-j2LObct=7XQ4py<4sC;X0yXT_N}nXxOz(_Fzf zueKzWos=Uv+>oMxZKM+nafAx`lJe`(7;1>x$M!-?hW>mLa8s#}m%AWTyE9v7t~evw zaKThz{YY{NkT05+)g5tH2l@CdfH@*E*iA*P^x~$bmBw&brgTS3>_m6!trNVy4NI$5 z-^-(Oo3Rk*0#kgNiQ%}qX)zc=y)v>PwU^5EEb(U5EfE$2@l?O^aH%X7kNa1dy7NvY ziCl6FnAJnD<5ANuClRE7&b3=U*~M$z z%GRR1YZe=-s!9IZqC1Xq9|&y#g~O@@H*7uD+fBwcydizh=FWrf1_tQfe(E5e&YuO- zICYJedFE*WOqaY(1T5B0W$FQ?$W>f)f#aHbT+h?-LSaibK))w7BH+ijv@n4KXx^Ez zm*u-6v#aRu^L*6Fc~(bqP6-^1-%2gAh0C_hF^7VWrIZs**@3qT-MSjSxajKq1poH7 z@coNb@3OXRo(h6TQLqdexXL#qKasP;mi1xTm`}5Cb+Y2Ja-d=H(&O2iyD|w@DpH7# z<_dM^4qnkdB)#NR)!hBs;zfoX-+>z}4#c1-ObY=b7LBzdy3e5w-FhRa09p&?x7Xrd z$?_EiGcThq(*(Y(M&oK*adw%D%OiWH&W}danb?;gJk{B9sS;PqYgFW?L*g9$K1$FB z-_D$*bNX!p1PQ@=L*TRIAnHYKLPT4GPtHM@q6W$=ZU?*XRMQZGyU>}EeSOwF?x&w< zs9zF~M_SE|9fEv-2o_X5@RlM%WHKZB7q}c{#}u3J@jy4O_HAy9rJqqZ;W^2-d1jld z6pOc{^wXc}hx3F`(vJz`wJxAjU@_rc-y{uLwAFbM_|TK~!Sqafo{rB| zhtD?K?{tL(AnFEQKOaF4e>Yd1G$1)l@W%seZdS_8xl;z2Gvo+hkmEOj3l%P5UMz1r zdMQ-@f@~tzQd#-)2=w+7SxB!`0a(?*H7$917bV0oCd zP+g*vgW$FZs{zOU+5lU<}yo-I!3&?TE}bkF~sc{Tt8Dam@6{!n2w6an;xBDib_*8QJTS>`mtfd{cVfSm)Hq zGwv`|wKm@!Yny?A`%Lgj(OGe(Di8H8*?aMoH@S;O z8_onw7(8~mDI)SgU+bfwyXZ`^Z$rHE@Y%h|#@ zXoW*;vJn6AG*dpsbaa2xqe%r{LU&|(qk8jxaZbZqkyl@%)l5=9cV0CTnXx+i;0YI0 zJaS_` z8a#;}!=gXP_!!PzJ5ZgD2)$!yEcxU1IHv! z#LIof(qnHed8U)<_(1hTzj2cpFO!W0;DP%WL-Eqs;@Htt8bdv0qJ^{KNx&jJuRYde zRNMm;8zws@5?|jb z_}9#Nm=-CEv84@b`Vs)I$ms>aV2?eu=4<Q(8=Hc6jg&a$mFp_C@_AgBWu6aHmX+Obxl-LFt8%#$Y!y8OPaSNN2bvVB+I zgl6Vny`K6E&ne$q{E{RG0!NJf7uWF#zm0T$BL95YW`q&9wBKtF`mDtppF(k97cTqY zUOv9VgRc3>Abb+gPW+w0Nv?b}Cgs#pRy$JaPHHiIri_JPu#!9L-k=tf1mT2zvmS6?EbF3cK>vIDqS~s7NhfUlC@N(QMM38Tz&sBviPF|2L9&^62w)>If6;b+ z^(9=&Ryt}%Q*X2)Vu$C~CjBc0qOp@FMk+&cr;g7&1P!3C zLm^I{?2(?E$C6ezU7uEmFLYf|P-_#roP0q|8E;Sun5g_O|2d1wj*i5vegWEI2fs`J z70v)n=NWU`nCpbDjrcEcls*90Q<7!>ebk?^Fl*fVVCYM8+-QV@J=B-veH}Y?^cg^0TDmY4B5h3kJDY9qry6Phqa=ayx1C3%Bq%ShsuG+8B_NchsJyfY1 z-o5$@qI~y!*Qg+&1mX0DM(-RD_b{r!H_6riW{WFqajZG??lDdAw%W0w0Is`(&A2-n z!7Gz_-R{EExB#v7isFf9gq|~@yJ@GyPRsFKv%B#vW0Do$7a9Wiwlb1UI$DH=&X&f% z`Z6vMnJJOV2fSTTGq>+xN=N8}L3lO^#?{`JJr{NE18Hb!_1^$h(^H6ujbet|4L z>i&;EEY5|ba>Kfpi(}9ww%Gi)ht<{Toi9unr2n&)R3a?Id!7ew@sQwK;mGm2I(yvf z)2Hloo7MX@Wk0QH7otPzWdGwz$(|0-uUbWnEew#wF>PSFPIG`3)Bqw%JeDR&+|G@7 zAtOEE&QX5aghtGFW=r0W?iN~~7_$+zfMSQY950H6R2Hqa2se!3$1_KzoZgv0JlVfa zvAs8fFa_ZdRm9e475jy#^xBl-N{*iKWB+ zXQi=+_pPj_J2NCd%wOw2^*hf0KX06`+jZ96M1C(42U)DNmw55j^t~{u$a^d?+7Vb& zQ?fYTjrzz9R-@}DN&Y4UKX9aIKtXJVRhtvSGL)fcWFiItW(gWq3jw`#F9b>7U6$XJV-0+w-syN|!ZL!q=K8jskldZ>NEx?|yL_X)6 z3)2;Sac_N*>718HS@O9egef2h4t^ouwIdGW*$SflDoa;}{MeOuLQW zUn7lhZ9h;<;RsQ?;Xb7DvG~kwOS%3f>j_Ln=o=sD7x0LCqt!-09>HH7p_p$C-&UD- z9q)y33Ec+yt~RFWbCq{H@mXa4mjw6kG$Z3YM@sG?tfU!bfKMPDHJTHNq9g$qQH9Y0PpLJawqxyv1;H-6tzgal-?3$ehS@91IU6WVIdP+9zXDz8X zhQTVlm$nV=WD&x(Xc0E%8_OY=_2QY4D(Y{7s{wEV*-_8aJ^6rOcgUY6Cw1`5m6Slr z$>9?n6Fg}nT9q@iPpmbHZy1Way{r}62-STo^m%L3E{lj-=!_-4W)xV20@3337(&DU zBr|vYwS#`GoUsG^6Owf6epW1B@%!&Om#Y8sC3MKIx&3=rJOood@doiQ6F#j^l&LPB z>scZz=KEOJ#?3m58$Gs6*GOCsAE=dgx)^_OJ6iJNADWQ!xKD@qQaRix^&Oa@M1hOpkrFSJnDMAs;-H zZu&qUV5^)H#?3!Zi`CCKelxq)dV6~3hiL#HeESz!cy!)Vv5^t*eeV-#pJ$Y9;ev1; z@bu;8@po7}7+`O%Y_I`9@79LU#ruJt@45#>CzuETLX0rbo~F}|OZkoKESC-5OO0YO zJNCDJrp8TqBcf^AWZhKmk;z4wsac%j+QR&odce@X$CbNX4;J}VBs-~suL-^yrSi_F z&)OtF(ztdg$0xcIU%I);jk}t($q|>IY!bVopYKa)^0dPf{TK8jh%hUl2p2(DUO@J< zA#@}$+UKu5(5<{;Cln2zat?P%7JY23)CgG^R(bu1-jZ~}%!G21g}iNrajkM3wq7jZhevFYghSlx35Ug)$pPS)6oc@k z-Xy;*a9(T!0+SM<{Jy9#}}0;WefX`#)fokxm)S`UL&zd|J8tITRaWBoa=9aZ)>v zYAG_Z4CDxWXLI3d!)q|S$Z~X__f-jYM&u>#$WVsdG~gnq5V)K`yFWF7F52`P_y%F044nLlQ`=@!Q;laA{<+5Hdq4>ol0 zyxr=zF|lyK>hFR-?Qdw`+E!YRu@**C013UluA^fSrui2R6Olwm3krt z)VWI(sLpknQ#TnYS{+A2Nw>r?)yft9=}wK`kOoDnVAu^`q$60v9V)mn)0sH?|nDk&g1kVSZ3`|FMe4Lu`S4>o*2^kLeMzNsFT( zPHXeA;8C6*JV(>0uUt41*SJ(w?&Qp;@cfhRPx{$$Z@u1+0|Cs04u=z@h2% zql&kL#`Ym6D(xyM33JIgv(=S2EhWoe(TlQ)vrh0yn_H)ixZj>x5fR!U36_PnPwvrY zT>L#JI}NIyLMwIt4;Gfa)8P~=5;8U zUY+pciKJd>KK9wGWuE?qmQ5^2lv(MVZ8)7z&;DMaTr5m!(GExxfd~XGf&U;Fwil*! z%eqZ9t-r`kyiT9h^o8*G%0)T5o0Bm8dn1+>0G ztNOqXVzeeo_SMXX$JNB5=QJJ}UbW2Qz_{XC>~|7!o$lg`U~Qm^yAcbv=G)eUfk<^d zs8@b#wl@5?biT?NeOws_Heaa9a96jkH`PDH9!AtbRHe0RmKQIG?=^hdNNVe4-w|92UhBFlm2?ZXH zC2d)R zWE*I9hz&m!{@C-`y?Zt?oa(!m5r|YFk1dt(8lQw~vO)yU?E`iJtkK!Zh6N z!hV3&T%Tg&&Fnad;nh|@+9Wzl#H54yEJo(kFHK(DDkpG@0ksJR+npne6;q^%=R#Y~ zl9!A}-O=8kq_UeDEcd!~UvTj+H$M7w>q+>=hyIHSYKH7Dg;qdWP!y>UQ0ln$#fFT= z3bLq61Hd^mS_{r3D{QthQDYS8etkzh^HHzh0GGHFMy`9MMqT?@4>{1nN@z}sq5wX_ zOs*+1Ic^8zDZz7jP{tB$vEG?JKD3ZQ)ScK6A2Ds8p2HB-xjk5jfcQx~pd6ops@M){ z;X(+P4}xm;`nUmtaV(hw#^QFQbhH{g_ewFsa(vxnI%0(6>YQNHx}v;)YiTLw9gle` zK@vM(k%r#1AavPId>NWwdNi~e)aGSphttuleNL*qv34=Ok4^K=n@-^;w4U7;;|1)Z zwdzkqDR)k4kQXU(#DjJi!}?L$#|FWUBBRlpY-87KKBvLtd} zX)h_bMTkt_rFp5A9JWy6Wj3x3^1DzM^su}>da>Wo;+A)cvdfhIB}?U-XrOTa@Z>|& z;}UWg$rlz5z9?Qv;IEAY)MrwS2~>2}8K#h`sAmp7S=d)+MD(1MEt_uiR4+YaqgmHF z(E*~EBjWlvl^c-0P9+>;0e`kZ?{=bD7c9qhA~6a|?{c78we3Erccn1($usB>n}BuZ z_hp_3;W~F#G0#C{iTO4roWD6asDSKis%An6eS=23J5I<{7jf)%X1pK`&oo!PtV$d& z9;(z<#OfC8(wyQxT56vc&^!mPZS~DyQNOmNLI04jN%;+d6k53{?>;e8`z+m-pbm^0nYFJE*2>I<2hz21tuDBhPahWQQkVu(tw+apYRmSOyb6n%V z6!hhoT-0d(JX8fyjBAUy(zb)4O)1rttUUTi*p5=?2L!blfEM9}_3_ua5uUuJ>?hf4 z8pW{%!pTmz@8t_E2fYolb9Fv8rS>(%yj2nmw?cKuGMeF|1RkEHq6JFa#yKj20^@Bi zsOL|Mb3H$&v;(HFWswj>a3nyk1F@i-(NoS^;d47nI>$0;nXcCpFK85+@+EQHld^vR zs*g9=rgXn4r(u}beL^?@4$d92?^Gv(L2dxxJ|?`%ESLoNa{FM|TwC}m21|3sy!*~P zBy8YZ8mV2iVWm)fI;AO>{hhp2=6A-G2GkkKX<|$lC=4L$QN<9~#+L~#CCA3VTwCy< z!o07YHpm{p_vq#P9A(w-;nQE%FA&YR-dFunl#40Wk3ORgK=`3NVy4dFW8O4r5KXWs zW^Z=FukdPXD6jEo$#!OaHE`Zau)i1A@gtb|Gq+=Zchbts!VBnojVE6;&s(><50V@8 z>QbmTMJocO^(TA%NOd@C&-3y$EAY`O%bPy5fm&BF>9DZ*iWOzGIbBo5Oy z&rIzHc-lxVasB=?}-yx7em`Y?=<;fT$Cq7j%0j*u&8Cqu|;F}_esM)G(LAK<*%-E zow=n1)+N^yvN{Ir1w$xi+3Spj0~*yIYMMhHdTCT}UyYV7^=mSuS1mQp@A-!Q0Ys^; z;BCciTqp@iK3+nfUY}>ynA=NSahma0o0SrC@~5>@e2!fQvnzg-zw%?=HcZZx z4_Uf}?gdY!Q&Fe;fD7|S!oXYg+X&_bbPS-jh^ne;X4R={8uj)!wUX8!9uhRI2!9g$ zEMX~l=<@rpGdae=V_jZH$O)tZMSy^Lw+|A8r(#o-(=uIZS)Q!(M2%4{0`I)W|Ioj8=`2c3ODB#i!#L@pj<)l;BP>HF(XUMMx)i8 zzpNt_#?)^>3lVZHql!h9i`MVz8%I3$ysMumuF8l%K9<6k+;Qs*d?;yfWlJq%RIg;L zWWU&NTwZGMN9I!Oc_$zH588Z}4TPerHC}bK_UT|%YujWmuD9G8x&kP~d1X!Z=DQH& z;8n+Y!3;Isy*mlPJ(0|<^w`%L&*lCnILrSGZTbK7^S=$B_HjG1f#991b3oSz)ggG~ z-H zEEj_ChGZ2g3c!(2B$Ujk##!3GC-*ijOv=ai8q+u*#q`xQhAkvt5b=HqFvR5awMBwb z4kH%88%D>9$bL=bF-;)<42lCi8Ejo;-RQowF%X5UwOX-N^7At`>KyoQu&XSwj%RA$ z+GPM^F=)l?9;1Q6i*_Mu=dmCm8^QaB2GsC}hRVj1_lHL8;bDYbSLsA5Wd6J+A30+& zG!&`uyW!akJhjcYAviG};TUU$n}4)}9DU0ksFF&8SJ+xcWnAOF)eAIPL>A@`PXK5R z;ma84@cO^sL4ga;|7)T5@3-@>Pe+|Y{|^VhfBoX$e>Q(mY2)=K`!e`nPjmlYPs~Ht z{6Fji|MN6xO_cu+@4~iN0*pchI`8CrZW)vW1Ijf)x<51nTNq$ubOnECdLI4nJk^ zFQEn$l$s#MtqJjL-*4ue=kxi_yq=je^Uaxg{|LWdNcPU&_r3Rht$khVTI-)5uC~v= z`569wHT`W%CE@@45g2vS``gU?{aQ48^~dML94g$bcaQh)bA$SA`t-y9KYLmIYfyim z?EeY(>iJ9KQTiMIb!6b@AKECcL3#af+DnsOEm*hzoPw1DlrVnxmQx7obLFT7klC%awxcyxx0hQj<;Oy9{dQ%neS z(aXLz<`dFugoVK@(u+5?EoM&IAua{3&se3~jm+Dgc2!25H|rMsFychqQw>M?ZJM%v z#)vioUB35&7!YoypMGdPE%BnAu+F@D?(%!77UJBRoFY@Vi{mp|nG`4dvgw>X9@>fJ zn}Zv)SvP!(m(B8dGw)PYAH`_z^ERPxOuB(V@u*p>on-#?xsUF2jW!42RH3jq{#7DR z!|6J@hA?ymI*=q4AJsUK3l>7*AL>-Lxgx}T3s02NXdj8&tb@+%wqZnxrqLQYt3n|b zQ!*4;mr!-7m@?6LgxNiq(qlV4XvS&d_s4rr1#1+J@VxlIv8EvVlg4+676*rz0&!G! zqK?;vk6#O-5=CY^*1YdHm6bEvcaf46U5~w0ILp~;c$7o`7Nl+)8;!0DAzEjYI`zxN zN-Hs|8`f1tsc(k9SWuJGRj6wAoKJpk`%Thj^{HUA(JN$+FyH81C=1;DOBeFg#D4NI z?>mIZClkd37(*S=ClxGgPSyKqbRw7I_MccGi_C7^ON-(*>z4K*G#$$T{x0@T})bOdBoG0Jb_ zLdEkE``*WT_uN7XI_<8j)V)jSjrM6=wCGdQcmM9=(Y932lBvOv>$JfmfR3*l^!i#d zHm+NlC}FR8de1oIIX*PCIR2rYmXA{TH=BU77i3gP@&uJc-`5MD7EexXD{pgJPbgQF z=cf;c28O(Oo%Feo!@lLH;ltBB;%B*UYae}PPm&`9zsU7$3JIqeqv641T@&j?&CA{P z0U^p2HMjjLPCadHK4o@lK=-6)FB8j-(GGpfjZH|yZo42O<3Wht=+^~*qp`aS>Nc1O zX_?&6P#;YbW8GcMT||P=C$^@?NQ=6veVeYF1SAA7@F`%v)JL|N2%2jH*;-9EePk8} z<^=R{6~tGTy6zz%R@c-t;)u<#nT%y>)^ZLP0yGis zA};4sIumYsEb=$f1m-vZtpu0>(CnXQDqDnl?Try`B_m&yd`=XYZ#$E?;!K|TsGp>J zr&{z3(}f9)ePW<+;0hGi)1k#o%!#J(u0ohM?>k^bv)jiQig-dr-%gyX%18larQH-bjlQiM>$|)9Le0#a3gEL zrFsN166#FsHb`n30j~}4WFlkt(csb82c9ANb2ksjH|swxBU%GjZLpOd?WId`Dmh#) ztR_=ehAqZ}f*N4eTt4Np=U3wImfxDzvc2B@>0z6K(Y2Nv4p};jpI{SMe@M81N0hXN z-C&q<*0<987%ONJhl=nUuD4Wv_sWc|vNM+Gbl%HtP&*ITdc-P33r0cWj#y2+wF> zsyP{YIx4s+R=OvnUUD^SQSVZj!WN5mS19iT%yBO*W+1GDqCOcUn006Fx*}tV?5VnX zmnXWF)n{kh{P`S9UvA5#-swq@=pW%#{;HAJiLLKxhaCrk=Q?p|g~e0foH*jUJ*ztS z1BwQv<m*%hk?&BnUx?Z( zOzumyy6KX@I@oyKIU-wXH8~DaDP4s)HC>B61Vn@UUd$p7?6}uC?=N;e{=(E(wf+~x5@}-+E=X*u*tulB`*&iX-yoC{2HdYrD35OrPLpKH^SDxqT{J?(Baj? z%e3wp;?CC;#FY2J=icE20f}xH!_p>|wc%}T%eddp-MMBVqoazrC41MqiboYByDdNR zhg%=zbdoEjb_*Y$5WMaKVfRTtVop3pbgXU@uM!BZY7TU;&uDP}zGszcouX28NLvkU z2RIUR^Z>KvFq`%ZJSD{rj++@F_a9NqZxdh4qWzJS@7JeJ_8oqBSo00HKC7DeKPE!U zDxMT|kgK6sjxZ!38+qbavJBdVxh@O@dZve*VXjAuG{#>|6Yvst!CPOn>?SKdX5jny z6+P$Cnau^rqgEM$2I*nMqfPZ$ujlOA@;3y$KTn6u#rn+ME6n^nYGym3A2(e2Xy}es zB;ZOGvqy*#K7vnxOFv<2dJ_+xW!~ebTzAR}I_l+3pn`J;7w&co46_ zQ08_2L-yI}udNoH0$+Esiu=*;mDrc&=0B^EMdxB(8;a~TsL;f$hk9r@FN)MAeIdbt za!99K)HkH$6vC_!c=-97g?3clUWWn%(m-d|DD(4T(^D`;Bt77d zPl_)0N?mjWA~ri4?!dgKn_efbHK$*n65%sA5fIaU(kk)V+2j(m#0bZK~y|so9(Gs#E4d{j^rc`y-#e^qaw@m030()FF8N zm+hB?l9_x4g`boxeiq0oWt8-&ZmzWQ;?R*<(ft^CgfGsBasP;hb$TS(1(53&76pxv z1K(i;i7apX^Xz<59qjD7J{b6-ZcVFf?23J^H{uRH%id2MQDiag##YL;qXd@bH!=h& z%6&B#(WO2d3Sp@?#HL)Mq#jyjBEiy529;*34BRSYvY6by~inG)V1Uf(IeT>O@VGCF9|;@Gg0Z9r+|yqWVB z5U1u8sywyEt?aCAS`N>;HmFQ<>WCWEMQMy!=K0OVxfN}Lj?%<$rhvg4xS-8gS;gHm z%JI*4O>+A^OKw*_cbmOSjK3=wUtObh8E^QWuZfky`3-+HGIx`QZPTs|Gr6<>Vjr7e zJ7?k+l*da}sxR^PIU!%k(l?tJd1S*#s{-YosIb{>r`jpw+WBLUR8#o*%V*vUPDTY~ zW5(F74*Lat8QoA-npf>rDnpE%gRDIEil>jZ={@8K>^ znaxXG;1^ZZx1qJ<@iezG={r$+lSM-30901=Ts+nU+@gw1`6(HhPf4D1t1^;Vt!awd zQRXbj9Xu^eYr5D>-FkfPcE=d?Byu2=z7rc~XVb;Xv59;BMCYyXpw^IBt>Jc&;lPdj z_PK3)263FITH;c=d7iICFXOWxc5&+(r|{of&fr5?nH{`U?>Eo9d;DVVo2{&eq&&vj z>f%u7<2>cjDYr*lW*2Gy6JL-QS{HuOq%46AUg*u_1HQ?=X|RU;UFd7h4=Pwf8clR4 z_jE`7{4-%}w*SBAl1@?y2v#q3xSWA=ph%>f-|fRUklSI_P03aBsNs2RDvHP*yA1oz zq2&LA*Z_{AkE4}J8<$p30GJ28Lp1^mgJvZ4;LxlFZ)2o$-@L35La*-a~e@%KWSFZ z9&kAv|LZ>_$wEDpgZ}Rlpw_(2r`+Xhe|c{(vjbhWAdp zf1TKWo%MgsSj@jJ#edyn?EiBX56U#LJ&jmcnV&8~TE6)e+Twrt?eWPKN=HEd1vO)SZ|T8*{wloeLs&l6Eij8~vzf3TS`mrCdJeH8%R zduSgVv`{rD&ZFS7mtq^0BgbO0V(M_t%~sR1%4+Eb&|B)(N=yT{Z_{6bmp)Pz!=1J; zn#~zs;IhH9g3eC3($$x!hC(y}q)z~^-yq~B{4^}?{Sx$}pN9tzL7CxCE+t*DZOyI` zQ!r89B62JAklyCo8tFBxyp~D}{B}Q%5g>=LZY-};KuJVn!29g`h`mZ-^_(o><#9M)?YvItphs8NGc=dY?FzuB#*a%kE=u^g5EXXVQ#~0V^n-uAVGCcPgK88H)6Xy zPd9;Y5G%d)z5QjGEHd8=mOKg$7X&}~t)=(v~A0EZ(R@u*FEhT9Fb-Gn8A6|)aMIvFYIg**XRlx%`~FkSIw z?8p`)o}cjDE;p+ys1n1q_kD3Ny*1q{{@`rlE7fO=Z^l2mH2(Oahm@3~aD|d$Y9^rG zkQ2btJC*ye4p{i(4W3|JL3RmOQ>3?@)3b~{eHVD9ngFWyqUZ-{iH~9H=V5GMw)=|4 zJpwQO;}=J`gf)IGSe zQ!m~**97$`M)xcwK?zn_FuZju(cPZ`Au&NQ#X}=-g)fSLM;8Nt;;ZH?Aq+*Z`nBxOG5;QC*(JmMD1o%m#4Zs2lXW-4(FO=C?^5C+| z2xS66sqdKv@7=3kqfenv6JSWW(mXVBr?LrZCy9Olb%Vq~*|cQAtD;u_b;(Ac1KhYB zDLRG_&$Z>ycqS{Y)GPayf%8F#k>)3Z_o8eS=K^7M-OQg5ZtFS{Oz`w2ssfW-X*E88nc6bnu!g`l$+W4=5_!KrvHPSDGO_pMMBv;jxt)i2;QUjPd6sCQSDG zTw*6fl&q_aCHbWD)Uj7QU#lN6_y}z?1te4xpdPzP7joi|!az}nBAnNPsJR=5tqFoM z^aP>phKq-$73b!>SN1d?e;*nY)GSNYFYYxJENo$so1?J4EPgS zNoFm;6XxA_$wKIu7Bq`W4Da=E)|f@F0z+l(kdL+3=C6Ly74F6Ad7R`}D&MzQb9P-u z&rFjnfoAe~ei@87kkgJ7i(=N&yfEfV-)@B8{A?|PZEeZ&m(?9=yLdLG^9AM>=QwXq zP8Dk+MVqWoxdikqC&xet$)8|68Zy3kEazue6GfQc`1bCN+NMejuYA0bDA_B7*{k3?x_HtwVM5awRLX_uGXrPx^eS`eM z4sVA3>NUD)AgU*&&FUhb7Gx`w&_H?*l#?BSf$TeI(jSDSajhi*;925)a7ke9j!;TtV{ANAuQcoMKa(c@)h%AyLyqVdJ&R^U> zvDL-Yy_kbCgYp94=~$2iW# zf!O4S!pg*#TAEWDr<}!`r)qU26XN^fbAn{Vg z^Zs-^)+;NNO#g22EKpjG&}}4`lB8z6zdfUG2XU%85r>m7Cq1ErN=y&o$qG8QT*G!H=XgcB0Ck6i zlREF#kZhqU+E?AgV|I@i_B_A)gOS$Eq7v8rwfJG+1q~|zZ91DK&A{|^QAv0E#z5cu+4J-O=SonvUX{mpWd2V!Om(4 z`G6J6+NIcUPD1gz`c2I(HE(Mh)B85Q?-->{E{-y3pGsU&zcVIs6j}-1RqegsMM>8V zo`2n)eNH_!3j@-jpiAL+w;eXVoNMNV{R_pi0grTsf-fKKlVxHIUmCE?q}h0N`)uBq zEOGrGDM0@}`Q1M&c8~m#Wf=&5`N@W$ybA3>I+A4rc0x<6CqyN&VA$DT;d*!V5X`JO zYDnhI(1T=^y9?=j4%q>5A6vM|b`%L9o*3Et2>5)bkfHJ?Hf+(RlKCJ# z`99+PTju`W-h8^R|Cf_xHp5sJsF!IpmQzcSq6;wOcinSak&C+Xx&KX9C`V^%+nc$A zT-?e+WW)0#4?ed%>P%@$Nqfcmsu&%M1QXe9y3m{caah(CWugF#-z%HDj`*_S%qx3% z>W^`gmdR5Mjj59!^$|wj-ZSlTDlxS*vCZ&zg*XWwlxiF*rQ86rK&r0bT|O!=CME-y zbGOX4=#+?Fy>q{b65p>+T}M@vrjy+s&O>9T4y}hY;l3% zRsG|)M)_BE3}^Bl1s^i9Zd+c>1U!B@J$7fEU3CJ~K&Qv9dX>PsvTp*)`>I5}3t^uY zmP4!p7L1OX9~qO(ZRuZO?Z!sJ7-aYRS>rG=qXFgapXvneWBfXU5 zG=+PwSWR+UYI;y7s0;|1R72!xpht(W+ClP{4>GyLsDQoYVT_1%3|LpXBYltjkx%w= z=JM+UG}IlWta++o-C|li3UY+oZe+%P1_xZdFD3t4-b;Se-7S}+y~V0&$F*hOg`Ltv zl;c_FM3fdudGYo?R&nGm$^{HG@iX}8@^#_ zla9CytP@O^yVKk%5YEJ;XuP_RzBY3~cTKUjGuNKVF~h|WypzpMTi1_8pX)q|Rwm-@8y%zJ1!Vd*FVs0Rv%#?x*fCYPbhg z)6kuRW5hF2#lezF2iSx2(6#%%a((Oadjz8gOWksw=7f~*QNqP)&CZjvjsve=CA>*L z8So<-^!>q()GrFUcSKKE)_O&#ePs`y#pyv8> zMLgT(*D)*DV9z36_tO<9IS|cQKpsIjHRP5dT*z)1NUk-cvW!w$x^jWbUyKPd({Xh| zemjd&Z!zz1PwD%|_1@$w=&i{;8ymQJX`5W%Ox8n40pE)OW6~?aBs#psq;ykQ666k{ zIK1?kRaS0JOn2l?Z<9t%Yx;dYdcNQ(YxmgTN=P|S8?_qZfj;xcp*tWaP`=Gexah8* zG&R%V6z3v40F4LR>3xO14)W~kJh2IbT1^yT>cZtXc;#ejp4Fe%cNTeh>#jR_oXYTG z8HC+LxgHchMP4FKrf7OUk@ZSz??1>2^*mSV98?(Dm^xHC?geZ^H3tKqQ9 z+H30t5eufzDa?d%QrZYr(Ho;c#C8J8yL1bhqg8|z&vQ5<&uYvk%O&YSG0bH|{4#ptcg=|ONCvc1!4Sp z;L)Sg9xVE}@=b;oI8=^#T}_iamMl40_*>J8p8zf9$m z-=!7Ktze7d&V=fpDB44l9YJhS>Ka1)f5t*ef6=fl`U7=f#pFIRmgjh<^YZLJRh{gx{+yl4*IZGj&;Fd z#)SLPbo9QXh}eTU$ESOzMRr05iQOObG|uyL|0vO839%N6h?6Yl`_Esg|FlT}!i^aZ zEe1^6SJqZ=)3#H>xGkKicrBVMST*F3Zk2*zPRk>Pv+o|uk7S1Yot}&U>rE;B_-_Z% zpuXq0)9b4Mkr=8AFcKo2faaBBnW4TMGlL&WaBgYO#LOaxRD1gx+qwfIO<=k))st1& zKOnp#GO1vqG$N+(0a6O&Ubwv$x~NUU0y?Pb2esX*FHrTnUnm2JMsjoWYUYpeWrMB- z&eiF5A^Mfw=oL?yx@Kq9)b)TkJ(tvOQ~p_z>h&Y%hiFxU%G+%B!N!4q+D>3bzDT(q zxh(e%CP)cvs`9-mNBc=2y@})_@pPK8$o~Cp7Zx2_Sx!&iBK{%P%RnSPn!?4oBHoQA z;Gj5D{H^T6qexjJUoU)?cfW14T}>!?&ZecIw#kgUmSC)8_P*+&DSr^of#Zx+a=K&j`w(MqIUfK%|YN@1e%=$CAjPBe>6e3|l40bZqg3^V#`Pu6-`Oyp-s=Vw5+?`kT zCsOHBY%AXwoiy8}%?(BUeb#^HDZ><&K7?bRBVsU_+u$#QqBxLrYCGP)MV+JS1w zXos>R3?|FyiV9``2_u4rmg)-!Y-4ucij+-Db8SjdZDW1>`v%i$HBODW*rWGu&>XsXjiXwq<2P0=kVp_wY%< z5xVB1eJRz3be5UhT8F8ixllD~TXR*@0Bi$&m&}g?;;qNF#?8|CT(XtZ-!Jvszqlu! zDB9Q{xA%QSDP?Ch*z;S&sHVj~A1%k+w55Q(ik_6;XZY_-bgRu;vygc;8`oa!KfPwZ z;v}1QPLx*tQHRU@Z7#=eELJmna(~ce(;6Hn3#u?|{YmSDQ?nj#SVvm0#y{_2LObTh zWAJ^=!g_zOM%Yx0>Mh;==$H&%Y5%l^sC3#}Fy;2to=o1^KFcjxM#)>ZLFTUF#9^)4 ze>>~{pgrhsyTx1tsaOF;575dWqWwwJz<3>y>PGT3q<*iMsP@VndYQl7R3(${PUU&v zZn8iZB61(SRX_|~jqaHZ%86f;8_gw5Klm!o0a&-MsR)!!eQpl=*tSr|b6Yz}gR}N9 zimE#Pg^IKHymMvbt_`oUQN3 z4fdBDQlHN5$^9lZG3|YQbwX-=K^@!=yN2(|H=+!wnAdRfR8?J4zeRIZ;wcrCCy&i> zo@vkCE2a)G-UxpQYIB17iCO|BE3|(}RzQFFjDOOW4gZs=NT9%h8lwK{N?|-%8F4gq zsHd|DlcQ1-_GYQuBi>}(Ie;z2`RKh=qcbzFlSY&7f4D7xN``u3XR#}$j}YSIi}2L` z9wz}}`HxSerWO^3LdRKe^Abb6=``3( zPRco`r#OOTx@dy`RskWTEjU|-*pN_Ly5Kh(l;x`dEjmbTzn+_VzCvK}^Lq2?YyJKw z#I|T>)AYSgFLvFj=$ZVJNNGvP=|;0|XvvOZ*nsK2QLU33c1Pe*{;aVk<2qhURc-1F zlRRoXY6XUS=j=~D>O!L6OVr~;vJ$|#3XP~;u(z*6MPbwkvIQ#(ioe`5=7$3{6SwQC z+nCGPT87G*YOZt|q+K@>^)uvEoKbU~Ibiye0qCHFfDePm4-%1r0Hh7VjxbqmRvE*H z>5s$Rww&KioSs-o`38vTFeL$3X#xdEjIC3DeTFb>4k zvGNw^>eC5GM+5x%v?aCwt+9PtomE0h#S_C~cCO}iNq+5<;8Lgc{7(+7M`>wpnq)SK zRM#e}*u!6scYO;{ygoN)S_ISf)m&&&s zP!8(Z&r7r#?8M_ks14Ej)eZR1+8;|l3K>(6`;$)~6mvR+8Gw&OPQx(`tFq7c ztqvy4bb_U~litML2#viN%_BcFNKUyw(s=Zyd+S5w+*0)m_z;W8#k5zsxoKWW^dY?O=R z+Xyf5eF2-9+0%QR*P5=4*uD=IRjFFId~9!f(Jk%EBlCX*&*^^}JS(ifkkAL&wcs-4 zjXB>!RAT>ZClSlr&O1$~7Ti(ZIuPvRtv`^V%F!ddeB7<3`NVY629{tBwhVjd0fkGn zb&!}~qm}D*Rruz3y@-!f(^mI1o;Eb5Im_F(q#{!Ivv_pAF`9v+6AID)gYdj3@d&zH zvQ*6*i;0BveT8&D5uvcghm|VM}@-CsTkL)czVxRkNL#50gM(^1OXl6QA*1&3%Y$925^=(%TyA3^V zToVQ_@d@Z30D3rY2O5xE-!dS=%%^LY4kL8NcY2~~n_K-zYr2_>1E15GIM((UOY#h5 zeP6pAePaJ!%+s)+DUJjSht?Lgp>a04%|za|EOTG;p>Dk-o9yn5PAb7q->Nx^2fm>H zA?1+%iBk4KVZxoBs;WPU8AH=c1as_6;8mbb?j0E&qk&CVE&;V`l-+JLiBtqTQ5N>`5&u@_?WC88l1aY$7 zdU@VLnf|0~rd*cqqVpLcuIXra5%qWqS=Jl0;(#1NSmgpec4Nv}5=IkSi)*2VWkUre zJ%#7e-RhpnwD+#xWICcYms;HR>DMaR|0j3Zdq0%l(yYq(>I!n;4$wCbjPBCCASp%Q zmyJpB!}bQv*Aw43D#0$ywX~aGI8zacSKWR@R-@b{QcDQKc)6HvP^9=LjTbK+qj8F- z$;VRy46d75t+rTanE-r`E0Mk^ z@k-iIXxMIV_}^;^lzdVb+t&=ngdG$Gg~5yfs}uKS=1B_PcA&tS(sTFvl-JLF>oo0# z#+D64*oZYcif@|Odar&w`M~GX+3%nL!}?0O@cE}{8K6)YQ&-& z3fKaXKWWmHP#tF|=YG<>DoQ{RYKZhdX{3EVpFQ*CAL7#uRDM%@^Z~7gD|q4L#6Z8h z8c-B+I#_=khxh!XVT7`w_PSf9N#zG+EnZ*&S_cRtpz*^XZo{iiYn{?65Xz^wFgd4> zyQ3rO_90GJJ>C4?nZ(vF-Mk&3MKr1n%1+^&qADTmmX`T66f2DJgXW6|T~iB}xvf3R z7w7IZ;@|E~2OJ-4@C02I>)yBcyUv2U{(}=pX*$55Zc52TT`=u7#tPc?;LGo9*bAyp zMJ&_34L8>C%eHwgNXy?D*Vx-*mMwAV7dHdhE-W^oR4!!zJn|9mt_vX9Tl(0)9nQQi z$>AT4cxA-r6?|rcUmr0S1956pOA~Q&8p95cu#T9suRr&_PnEC0nw9H8KvwG6dIiOV zn-*H))kR<{U(E^D?e9^hm<%NS+EuCPlEtZ;6-DcgOL3^>Trf$V@Saey)Mm%Ik>jBf zzj~xJ-2LhT1~o&e30Q-)CRwVwoG%B9*t-dLg;epR~7rU7i>FHJTty=*igJ<8ggkN;G92zk-r&|r5lbCvuT32@b z!s7Z6s^0&Bh9gK!(*n?hhIc$U{?jeS%iAHB$9)l<@x#q6)tP**OQK>vP5Neyvz8uW z;e$v|KnhR49Zl9R+9DFLE7%TxP?k|=xjwG|9%95iTX6C}D(N3=NMHk|^H z4k(Ke-qE9tN)JSrf6h!;HycsD+4^?841KGp*>k^9#yLrnhlGzau9Y+l7ySXx&8cJa2aixr{NoFJ3Y@soxN9<}aJJ*CVnyAkT+Q+{}3YVku@(hgq8 zY0oW|oAL77FZ}HHAoR#-D6^Itf)&UqLs)8Y_&QS@$wq*x17R>BWNHLc>QDEGwv;yb zPNjS{!!-s9#zx|p4&?Kt#$7hJL3_3|nSp5i+zYHvx;yruJV$DwdTRa6c7X#M29ofv7iCZ6=&fw*J zpZit#7Nn1<$M1^vJ6!1(5Yrx}%OJfwNCahouya10Fm8%RAs|EHLIe?fbO;BJvYW$P zRg_yLVAu(}_RTFD)gw1Ylumun_pCQ*Kz_V|9SP$KtgNDZq>i9!JhrpQ-U}3OU@44{ zy$V`2yrHmT0iRrWh}oplT>Li7vb9mwZD6WF!QR0Ch+Ntcle0Vuy`5(>4^CDA%tS5l z;ZblIl2l~Kh)?9jYn9{UH}Ohp$rgv<4CYfCQ7!SXLj9xwySXl|) zYpt^?Cj~xo#1u=TkorkiyZa(=$^S-3`6>HZnH*x@6JV9Z>BHk|)OJF`@ zi4`H9-xI(ap;Q=dWASA^VS~5-WUsYkv+tflUNLzutcom&um{Fhc&4-%k)t@KdSOMv z?MD)mzOVha%AKYh+XYMS9e!vHn)1a*l(Eo!PtkgxTRyZgC2mmi`$Az;G5wfgbP^cH z|6sw+jn}I$dxfk*pF^_le>MK3+PcKqX0fc-$L|Vl!DF2HAOZ3K->-*3& z#$wIURg|z6C&H{AD9NRcVGoJaV2H9$iU#vwUN(DtBA_Jv%gds+540Ro`czAtYuB@% zK~Ew=iE`Vn72aB`z$&o_UwgqcLQ8m4-iH^bl2c+(yx~X8d$Z`5c+_3pCFJ{!C^hw@ z`D*05F@@4I*8KDl%;s559C&1r>hcmFJaC2nkaC-7vcH*77>R| z1RXuhdej}O1zpZXvFz_AItf$*W~;E-q21N&*g(!f{}7Mj&*>bWZPq2rz~(vJ{G7^o zPOV+dg@lA)Xny_F)Rgt;>}+?H4#z{?i`-V0H)!Z-4!t{ERC0CbQyxJSPyY@zw@$JJ z!U<9s^0)-fkm=mt+GmL zeM0Tasqx=_Pv%0kKP2KPC!2{~!{Joc4GhDy(t@1bSox03SE)hkp`DY7fk7wCEBak* z(+J!(sqaKlM*CL3uKgK`$U!#L8#QwQ76B6sI#BJvh)gM=nBddK(+Ihs6)E3SN_UB; zt9Yubug^P_#CeuQ6cn_X%M0_XGM%aeE5j{-A`!MC5rw*$jI*G!@55L;o8-Er%JtWW z6Vs0LM#y@Pk{o(<%6~?1=2yqgrX9xI?gxTvhjBV5%SW zX$r#RKJLA3tlw}9Z-i6h(_p>4PiABkI@>LzXdI>P<8$+RZj?B~3D3ympyfRc9nBFM zGq5C@!^%fF3?h{{iv2-pi(EP4`WV8f#0$JO+8{CI71NfZrwCa5v8UE;J5%*uY;^bo50vc|)MXcUL2g#G9mTXx=%p@>VLc@&ftpy{ zwo$ThsI;8lOxUke0H{BNvdIhqBVc}RtB%fU3J{sq| zoj*pgIw*4U@yX+_?GIB3nsCXsY?|}>@O)WiWVq$rwIereKCy1W$mb~rz$vmW;yy7X z@m4?~yup&t@7eUii1B@~y%!QvS(SOIcv}qK7-cmlX>K@w$efRwIBKAh&Iow|i_Kij#-SOa(pcGr=D3oB`P`&n9w-w=6*&Z}6B;TY zdm)qv$q)RL2US<6qjvld$`$q-JnZ(2czkhfT2=O$9g%Fc{Kn`HPx{Z@y5XeT#=V8* z!`?*4W3-4KTkEd)gY(zDFwBJM*t=oDJ8G}Y3i{u8x^y2d7Gsv%-Gkma!E_UU4?Puk zCh%MpWscgLQ~9makrD46P3R{T0`jZ=Y~DGnEr;H~rFgT?jQMG(m*AZ2b$kN-3k`&D z4!RkikKW4hOgh9eIp5bIx(}r?)GYhsGVp89SLK)}9?_lk!bck3RwcIypc2vh2Ns>d z!Jj#0=52WG?$-3kH1&$|6x!y$#R(4F@ec#0QV zW0lb!`l4K9juaWWav7)uHDB%{a7>G0$u_6Y3w&^V5tAFjp*!;GV0LDxiyQkohXa7N zJ1N%J)exgHyh?T4LTC?~oGv~oQw^>Vi@M2j%+}?$uqs61+)*~YyH-x)y$(fR$_X8y zD&gRAGS0XY$pAho=Li6K?YN9CP}K4hZU+>DzcAPFxM1j2(^G{dTay6pZ#Wt8?_!3p zpI$9idCYKRbl-HQhLkW4#^vW){0BMq9a4~lGR)bo6`$rqAwDUEMTt4qiq9WnEZB?E zGHwK()-u7|n1!`iny0;*&K#HoW)Wk>aQR1Ts+$8JQ3 zN@m^S>sRnRtFf=fN2kFC-)#Q7>>dF@A^!fS$RJ+7hW6!6(yLF zgE?&2@C z(EC!aZvt0edlk+DkylclmCsx3KIv_ZrxCsSpe*#9(Bl$nQgJ!Ab*k_9yV0>{idPOJ(BDp!z0AodM_p2~APqPT zLWY;NHOZpL$uE>E03MHyq8_OuCM6QfYdz|w3&BQ{p%fAwtH^t%e8U-Ni1U%-5B+Yv zS^!4DV7~;6mLUQN?%~U0V0E6gMW+A=GzB7WdnAdf1ODF8^3Ab=Lvc!$Gs$(~GU2e6 z{cEL0x1jFH>;9x?2al-GO)zKKS#HgG97yhVVgh1SazX?ERA;)KwD`7-h}0*)m5c$l zw*%5NmNe|?E}TC^&1z|dTD?3=p3bLU35e5%sZavJ#7z#thuR~EJ}~&2`QtL?7VtqE zC?I&t_p|aYVAQt-=qea~9KJYQ!j<=Sc0Y^D%=|wRzWhT!*FS5=W=}-JLprEu$Hhi9 z%v}9TY>gvG-^`>(RmM}&Zfm!F2ygG$Uh2cdBOtn{2VXYFJlwj}wlcpO?fBwGlUrN#ZHJ><{J+=we;cF!DFckxP$tyilOuMAN|$$8yzZNfpV3jydU?&z z@~dEqc8`!$b8ei@%}(B3$u%?loqI zKfE2XmID5D8Gv``zwWcYtfv1P_vN>x=>H81+5M=j!p}I(hZn3<{DsQPn;ypTT@&-n zdu8Q7Lx1D!HkSj3@r|-pf1Oc;alQi>5rc1g^YEtB+VD)vmsR!)GI8I%Vf8fWRRpuQ znW4uZ=$n*NO@F|VLyuaH1M5}^zZP~c@=4U_8A1s4SQ!==3=`M0QQVP|?fJtm|HDP{ zABk+*`va?#Y0w>Fg0|tZ5{cpyviI;9vzraxJXAzv_!WMZRbYi~zbt zZA*YiH5j_Uf{6gK7qWjDAp`~nDLJYl%*gDQjhkcg3lu&PdXx2sxE2c-)wnZ22d@iJ2}@0VWP0Vf(KI#2TTGB zKG&0;@V!4;0?)HPYsk;v!@XH+4jx}Gs5PzgA0^lRtl4MskD7hhlhN?_4l4J!*c8Py z%)f9}@4+`-^D=qat8})#MZ`i!0_h=hQA)L;7_x74nQXMUZBhhy&ae9 zrNq#0I<;zF*aw+d0`y?`WBEZ(Whw{5-$%%A8%s@lf_l=w5Q8TKL=5VmAb`Rz#PAf= zagp*1F)aN;3~3-@H~}Jt#3N4YV4VE@lf2)51&ouP0^k1Z*Dp>tg0!`Ne@c>IL=XQ3 z2Xrvt#SkflqN;%r9h7Ds7Ww-p1{5V$5M~JNvr_o&L7348E?^_dJ0N52xBo-&uaLjM z%Pt6B`atlK1QN?Yx!*vLVE5YxW}w&b5fEBMhk?+F&KiVPcR*AFIz(pc{r!{V--a#? zL`$!H{xzikeysnyL;6x83UlUH3@3XbS%|_JrH*Ga&do0BX@nb?Tk*XNoepu*A&MPZ zHI3c@`(^yEHtt3iEWHd?YI0*a)zT8ja6J2= zROR_^6+11__)7Zj9JUi*sf*!(OGk_=&;PiYGxU%-{$F$X*W2b_x5xh~D^9D<)rs0| zmv$iw!?#HrQ+S;&C0Suri;+@UZTc$i;Fjp+2aL1#`af#A<=cmi zr<_Po=k`UJ9)-BD9NT{_)%=h9CgT@0um+(4>n$ws6+)Orf#`wTA4Cr%5IrQ@j9FTY zS9<>ny3GIlt7b(vCcZaN1?Bz`y34`PEj)`NZb0!M0086r*~MS+eH)DL!sz_sysK>` zAWl$${lW=)_8?Bs{Dl)HP#tbm5GPo*fH)y?PL8Sx;spJyNQ<>4;1(8y8*vRF+z18X zMo%#qL;8O~l2SMbN$Bfgl>3;}+(dP{A`sd9ej+~0ra1a#)h;1N3Y0M1{ewORy_(QB zg>x$K4^ikoMjNLmdhVLx`);Xeun#=xB5NFsF8_o)F%0K{8Gq&dA^G*m6ZgX})i9gp zf69$ZdGsGN!2V(Red^EP!{4fEtYl||EvT5YJ6qI+<6t|0o10L&%A43BiZyv}McG8E-3EMi~1Pi;=7K zPM+-mEkKqdj%g%$6}@TH+(K~6Q8?%DHwdNhR^3Eq(B4XCt_ zJnQbmjoqQsBdDs~t{gT>z(Hn1p6{TG%jU8TDVk(TIgJsX*oQRSb3)BxYs>Q+z99Zfd*2z=)V8i26s3!F1tCaP zA)+V(3PeRIA|gdPL`AxQ2vP%4klq9o6qJa7pa_w!n-ZEqr37h_P(lJCodgg93E@t^ z^L^)h$Gz{k``$b57-x*TfAA};wdPuDuKB+6d7tNbOQx~yq*|9BBZ=O7JCTZ1G>dDI zcAH-asnQSkP>FvVw5(58{|1_|3mJ5aohcWi+NvdrWkxNkOuoz7<7lF+oGR_AY%ykm z8|bU{4TplXxs){Pr~;}ozSIh{D*7=@5SayaZ#a4KQAHi`ZC#kAf|uHvj8g}FOrINe zWH+tn$eZ!`)?lfYqy#0=bV@zPm{j3wx|Ka`G>UQ@!f7v>IMA1DdK1n6*o?KfF47|AOk>0EB`GBXVPACQ@h0)okGc{ zS&!czS~W!&xL7a_q(%$mOMC0oK1Vfa>cvno%}_vnCLdi!k%j4)J2dz_e2{?zjrnG* zLQ=j4ggu`dTE(c~hX)61+a;=F77{K~)#pcOd2J*<9qAEwKuYv_qlKd4TW86gK4<#0 zjC{Nb&!yR(3CTngle{gOyNC4~YgBj2c{PqWI*@(n2Xv}vr6v)-JxVHAjJ(4aNC_w# zLkPHwTAj#x^s2T;S&i#P;z%V2zRJlv?E?&(Hvj0;_S^kG5nZYg4?ZE}d!m*@K~Puo zsYRe?>1mL$v!1nuu9hat^&Wp*nd=$`xC-HeLcuO%YeTMNhx^+rV5qSgrr=Ph!Y@Y0VlN)g=!zgInGhIf5v{ZEVz5LXgt~vi$8&kv_ zhZXt(S`^CD^qYnjd4o78ll6Y&Fxgh2*%LM9C=Xqcz9PPd2kh%bG^LJh$ys!{H&MYEJS7J|s1x&_(KyPjRJ z1+iMw@yT3ScxgGM7M^=v*dp;i>bY}B;<4z=sFAC3vCJd+J;e|`jcXD7xg0Vti@c4S zhdvI(mmDyEt9huPtWgets%C5(mpR52ar(P9PTzB0&@So^wzV>)0VyJtCp#r zqT_reb=TsLDJ)MKeR5G`XLhk{sBNqJOr%CVLDws|w@4WclgKppkx#Ha;M#lKOEYfB z^ST6Y3Da1kHT$=H3xPingGOYrHvYS2vv5u%;>`z&3EOmp0<~nbBk_*47b#%&)V&(d zHxRacPdMBmyvVY7g_4&OatonWt?2cA4N%nAaGy=J8Ijql->u4}117mf0iY!f9~O|M z088Z>9koIzB$N_Tktcpi{wVyLG31|;KlIrdet+b9+7irY95t`|ob@>iR}fqf1S;c0 zDS{qxPRHzwUX>5?xXoXD70r47iKInR3+A*wnqEluiGg2-$0K%Cq3)(Tex1@eO5>H1 z0IF%&Fd?8kq4jpAY1}iS=KdR?D7f3Vu`9fm{+*%YPTEu0Q)iktE0!ZlL&Oku3ubM@ zdygv}*#DzTDr$sBRj->_Gr}SN54sRB)jw1bOKJ$KKfG`<2CKgMk%6C5VD5jNY zktLNE>M2Y(i7YMGt}K0C>6{r^Nz2i0)Ux_Ws#2MYp)4k%gpg2BXy&H1AWzX#$Ff7` zPxhK+nmE`tFJJ6SH1>53b?IqzP6X{FCFE#z-tXC0itJ|Gf>T;iMD=l>ISgvdWDuoW z-T*val;}8ZbJLo%89OK+F3U0VTQEV)?>v916fWmLo`7AttonIKR_1C5Salx;nXg9D zYFbPn)1yMzFL&UQgY?Q7Q9=dI<;xxD&JjDC(ZSEMqv=9wO@lHTX0IinCwA(mY(cK4 z5DRfSGE|kec9nz;<4hbs`-kFb(hv{%w!htoqRo-YjI?PiQOfP8cAc62fjZbb$;QZg zlR7_FdK;zz-PE1hj)QK~Q956UJVQO-7Qb*O%+Ibny1=WXecW*Tx4wK&jna8!v|ViK zd~-*WNC5mvyZG8o*rhZAi#vv*BIZWgB}9e-!*wC>p$Ms=_e@ob-<}y5aKFjouge&4 zFU+}fW%p+p_we(}Msro6BcWU+$yF3oTnMHGFXXn7QMQMn zP>?52e^(jt&53(xwEJ_Wo_4lyZi-(7R*!{;QjLr8_X0_rYB2paFU&AfxsU1d%1CKC z;U+Pg-Zg0#%`P|hR>JQv*A?Hxs-j139r=NwD+I>PGx;UaE%;bpcgI6L4Jw`}(G{;t zvw94Ne6f>#nFVi3VLOJ6wcPpUQr8o-lsiNk9W7J*)ie-^aH=UbG0>J{o{fyF&U!&DW+6lV6Q+4U)SAUTz@p{?F-eAsS&7fH{>I=p8zXyUPZ^`Y5gqws!|f_*AJS&CM2nxHOJDpD4s}o`PZp^eOZt=ec;EtFqD!Z5 zy7aS#q(jA2#nMD7&(bd&;7q2&E|zq=ff(_J+3x>OK!r-N0ArsAbnK1hgHjgf$e8v* zI<^Vteyzt_LH5D`?Ay>Jak%Y4?&AYX1>;VE_Aw?gNHvBbQy0v1w8MF7=GgmsDo5nX zyXWa`Cm%oAneY6dhH3QX3DZBkhm@$O6bH^xiZuFR9J1$ov4{Jg@m3f%RciqTM)SxBcO(8 zYeH{4a9xWD6}zB_0!V=|W8{<-l^Nsoae zwV(lG#PzC_TXzB(@r?(!^R}$Wjt9U{-XQ&ItSMq!FtAq+RW*)S0 znN6M-xGymAO>X3=Z*sUY0Y3KdvLjQV0qk&|CB`QE3^K2Olq@HPf@i zZus!C(7MvrE3w*5Y}VD?MVt`LVZP84=>V@@pve)TcfGW(jPo7zW(tj4Bd={i1bz61 z+)ogAxSL-LeX7n-b4hVKNIAkC4eIYHBPp5Fm) zb&;X)-IZ~IRGD&Y(W&#ZKjR^xf>kQD?mA9l3KLE4!v&ew$UYp*lYLrtAo@p7HU?GL z*3`!jTT3i$<9zP#@-%Ub`Dt0nm0P_hsFuYIjDt9*u!28Mp?T|i>HCixJyY0G&sH^L z9O`LjBzmpGI;npo;G>ns44*0e2e=(PP5lEjmUWWQAcZtUH#>^cU)+@VV0&`9%%Q6N z>%L;$QwA8(@wC&DHsv-3XGV~hz|FWb)#&$Vv*a2a?9`QXqh1!2Xl?x|pHr)^Z+{OW z>~Wf|%>2?&^vJ&Kz8&knSw@4?zKrjWm|&+JQQ?N*&{3Sxf%GB84|~63UUf+O%jPKS&2xx#njza+R#~4(M*BnG$=Y{TomgN?F;U0_ z8EzSFb_-&<=>iBF+2LUM{$xT|1HOex1XkWg=f%K-=%2LsKcvk5IaL48*(C~$Z$U&@ zy-vWN<-@jt$(dfg0jbG3+cWYVuY@zy1IYJHl?=8Zbx+th^Y8j4ZUgx^wYE-T3!-BS z8ZQcM6auQs&szBh*KUB+JB;!HS8x~#B<-8#V5M*aJIWEzS#gN~4nu>^ilYAjt9fcc zKgVwvu$h8`evUBcAD#C9V&H*6>MSJSUosVcn6S?0vBUyFAIf$F;Mbyl_Mx=>JFI?q z5zK3R1{O?i79eAPtVA_0fEI}BAX%WB%%GVG|G?^h8CS~h#_kE~4}Yrw{CdBj0QJk@ z|6W!2b!2ezKac(Im5N`+rO*6z=v9Bm>i>GEzr61M_CsA?Go=}0T1_PAXSCFuUhn9+ zV~8ouukSrP=VV}Z%sUXiQ!goMaIBhq=bvZ9 zzv_}?*}!K_8VuTxHm%9%$EX?GuFF2*z0K*PQmPnReuVdpQ>vjQ+ry{3IWguh5~7|h zG&dkO3s;^wU7?%r%aVV(w&eaBP$#O{Jg-W6`E<9uLsy3FLrG_S+pm zArKGXGXaJBVjUohQ~|O`y&wR7JOb$buR|*aq=5fdLipv9px#^obduYcP9Oxi0-dD8 zKd}B^FL{edN&!8kk`N-{68d8fiU@0_I%ar=c%S$(>XrME4>$dv>2(Xp|ET)y)ZWtT zmt$?-8aY9-7>DBzM|Avqdze3o*#BvFPbjUp4d`ZCM}??`Eo2RE}3FkR^a3g4`em5H`pML$@I9L}ewA%OJp8ZdPG{ zsNKB`>L~ImsP#~NCa9W&z`n`i;eOj1Cv2<0j_NHy(;&qq|^Y0Hf|r|50t(0d^Q?^q*L)vpctaw#`8`ec@0ERhrg+t=Rh z(W#ohLkF8F_L|5sW9A-`8C|~I5WJHvX$NiKb!cC`?{9&v@a-O~<9*@#rbDVqaP|4;h1aSDK8jODHE~Yv zyKm>V$!ebu2V1wM{pb&fy-ZyS=+6;|n^x^~ed(6NSs|q9!k0hTvN`|)4c_M5?NHHc zjs`4|O?3EfRFipw(hNz!Kbz3M;NM3;%6jq=a_;M zTd20}oRv--`U{^3Gndtrb9@==DWQZPtZunL9R|V)@A6%buAxvxJL;ltg!&@ahJz{R zl2Xzx+>|BdsKLY2Vr)_M0TU)MZD5>P^;zvJ5&<=JF9h(8#V1+i!ik6Yyc=@Ir3Nr7dF`xphaDT)BO&X`Kf7G&MT#9wy$kP_esn4*P15G?obk&XuRgiMg(@Bko(W&Xu^SY;wi269i+)ZU>m=e24^Lxfb>kP z1#H9%U$nnNeB3xR*)u?65A>CL&3RQ)7ox9=_qF^_4ms`RL$juj5_hGg=xWO-<^g=% z7G%W+3G%1A4N#DoX+wX14>o~3>(FzXX*=%ClMx4R44Y&wJ*_cM9Zr9`L1_JHM{yM& zgW_vY`HJ)zVA@a?B|Ni^3k^*hQ<5xZxC%=?KYZAzRe9Bh%giA=a)u299_6pMm&X!z z1!vk&ZUEV2BZ7YmvXqn6>!LUX^2DFik>9;7{XZDF(&2IJgCGP8Kviwbkt3!c?i?l)afxVau0=a(T3 z(GE!;{@DgETG;eFM~S}OHBWM_m%+67i2`qh zhD@9HH7Q|(HPtmy6G!dP4?ahIiFJCw0k`wW3M<9D9Cla#Sl)6+=!4A3XiF>h-4@g{ z91lVWtpU)o1?(7}oq4PmcpKylnGjgwcB8gKqr=mqcS?psB5uATc~|6Gx^R>4=SOpB z4twOadl_b`t!Pv5s}JeWB0Iy-LVAQm?DcMF>%5$yEN0c>=Evo4mm{lEA3on4la=ty zrK#i4(Lk~r>PjaP_GY#Z@IeS| zLh$=*2e}imcT4?i=he+Z5jqO*du5jHrI9-9^J6=>@QtjQH?{rFu5m&( z!-`>3Df6;x>a3c)T-ejD>r3bEzakdkn8^2-Y~Xmn4-7B$=S5WQgYazwQ$5o(+lz58 z@vA}d@qrK9Jt0^DoU^6D#PYe0vp0@(iG9J(g*}#n(hVBcT77BT;WwsZ_*PARG<;pg z(mn@7)$n{~NKMm>#tALZNC^oFY^49G36K5p?&-C_TOR~>7ko<_-76^1o_xbugo2gC z-b8F;o)DtDHU*l_G{{x<`6p=3vpW4?Z;XnD&)qll6A$Lve{b-M?PWvAyliAT<4X9) z9NEqMs{GnYT5!+t)gG6gQ5=QnStOh0qU`;`V4>upN#**Dk8%#r?v*0UH{+1kDlDkj zXrvEcX4H>P#6^P78fScJ8tjxRU~`28d73;<(lVySklP}w zw4L;6Qu(k_f4)8Rh)u0m&`-Sly?eMtnwXD;2BxAjm@tM^P)jpQmiq0f)Ujw2 z&LET4z;Kz~%IaQt&!a`HrS5tXQO8;D-R+WZ-kMEaJ5Rz>P=K(O)SyJi+tT2XNIM@g z9ce_iqUIEUin7n+q2uX>ljoW#lF8>fVs2ea*4L2sP_JszlpHN!II!?1;c-LF;+e6$ zR;iy{h4TkTf_GQviW_-NcF8O`3FgOI)E3E&7fCzP+ZYBxN@IlyOcjw^>0$llfzHWIc6+X{boGB7beq=9Bjc)jcD& z60^agluZeMl30QfxD|jf z&;Nn<=Ct5Jb^)dw`UUF%GlXtKby+j+4c|W_NVK2j@{@mh#Ma)?NR`NbOvET?!smfO zKCL@Vg9EA<#8~Ca#yKkWRq>#N&t-*|=%o6>J}jVDM*{j+?#HV!6kaaJ#1&XC&3$># z+oezP*eJ%KIk99FI+n~IPa;BH0W@Msu&idNJi_8xeFjzmo8zvT6W=B50v7W2rDUGA zCqBhS!97z3$8qH&iZOM1Y4SNwPE^SC+S%JR-h_P=>_}@D)R(~-@RvP)HM5h?vSzak z?y8i+<>9EVBfI23FJ)wakqR{`x^bWM)UGVvz|tWN{a)Ja{x-k6#zC#5w*l!zOihqC zwIq4AnrJt~kR^?pI}h2edmY5OIe2p{UTP6K%byXrvx|pqU=9>&){^S3y>g(}P%w!l zKa4|yD|f_GdM`4Rj}qOi^yc)xh2_>5-kQj~{q^jv;!3X<-Js`?6H$8ejm|cE4`M)c zR$s(-z$A-v#LctotykN@T8{7c%5tHoJ;fp3O2_-OE)o$<2=0c%baV1ftY;YPdwkxz zG|iF{*Bp)e8a(Jj>Lc%yCA^Vk(dix!Op@u0)q~}@Klp*Q9GL3mt<#5sn zXXrmxgz=GaI9=o*z$U0KZRyask5Z4J;G4owZD>KJ5Y4w>##cxdsJ6=f}LN&HHBh-H6DrDeKu!Vb{)}_ zJ*`FiqB=s?rFXq32SVqYsKL?6u7!EE;;7Jrb6)w?=@%Q4=Q>|;@x5`sIY4oja!wkw zJbvB6d+H2)9|F~+<>Q~Si(YI+BgOmF*(l_ahw7C}lJbC8-0)rF+T${c~R^A z`L-ufif+6R*zOX(%o4rw_h8?^xK?~{BV;H zg%qS;qw$a(V_eBT!a)rP;jh-y1FL0f{nhPxz7nSlk9FJ#aK809J}E6ea`L*N&a4eq zru$zpANw;o*q@X6{x9mf{ETS?j7Dtfs5eGqB@&l<~Deoe`Yl(EMy9sk2`6Y7fd~UiYoeBdT=rg`lI-VuuT9@!}nR$j?n|# zTZz$vVfveg&ZpexSMNF-nVy)VYSKK80t$lCOHiuPq)UycfWU*GNN*xa6%Y`J5{QEICL$mpM5KfCCPhLA zL8Q0Pl2D~4pkYhe&GWwZobS8e`Qw~%$30`5amTxo9X4ZUuf6A5zctHm&K>F;6%9IP zY+z&nI&}&Jx=nk5s2GrqKGf3<1Tr-RT>*hWr$Kb5xIpx@y;HOoD8>`S@Q-~ENRsv! z1fu_V>VF;mNcV3?>A@fA|81X6`0p=L_dwUoJ^Y^e1$y{B6;+nM3c7Z~$duvl-e~O~ z`x5`yJvSwsIG+NlWBB=!<^3*jBb?d^;yg_!Ob@0%bqPerd5WI%6tx!wrriatS5m&)T;QtowACmpo1dI58CE33V_P^v>0Ntd4?C(ZLd(+d=(WZ)?))<%={%%an zO#f)i|93n6kH+$MWBd0;rFC-Z?=$J?8EJ2}(@dxT{n&qbhq^?Ar4khdIzxYo1}1t= z5ClY_NPmh4{r_R3j{Q>>;DFFcZqnta^l7puV4dSN4Vuerz0-z$F0|^mTZrH5%_j^^ znzEJ!iGO6sm|ITAI@dFkxJ}UDJx~0@74&hB4t+1qOL<}R+2o3yePzSl>n(C(J%KXP z;!*dk8M6!m^urQ}w@A!5vpqRnh#jE1x^?upqT5o^lF7t#_I+^*WI*s`Pc6Si*QE|~ zDkvg=(q#wVHNtIEz~>h2y*jSWy2+I~FEA;}a&ldazO-Fg!;yRVG4r7YYjLB)hwS~E z8yknZ9psPUvU)gPv_cX^W67qegg4^XSrf-l)wCh+sL9H;FN(|;BQjYU)Fu-*nTwzU zeGpWY8Hmz{r_2xp95dX9dIvwI(AV&O4V zkWWeq6@PD;}Yl zud<~-DjCyXX{}f{jNOJaB0UaR;a#^b0+~crs70SH#~948dLRf-w@X-y2*D-z!ttO+g<-@GLV-i_YjWk!;%VMW0c@ zjU{&A3!WjzC%q*^dDo{S-hm7PuLC%m#aSQSD}TP&P{8SksL5Qx-BXxLF#;?Vn}5x|#pAXJK(5kX+8EFxSyLmQWw`R?+w3(d|uNjp|Y780R{U-eP=pH%DAJ zFODM~rY)x{yX~Zmw}TGYO*RVOefR~p-k;r^Jd>d5{$F>eun?<<;VMV^wxIA-QT2 zk5_71NpUSdpcawFLzv(fQqd3}#C%A^my*|v@&{cTf3JbJ63}T3b^eC_a&V4f2%bSXZ5_w2& z(u9%vdv4cc@p>y}jf+40;{h?kH-Llai0pGl!3_W%+>g!v6YD)T+(b{0ol}KR*-wJn ziBtY#_j0@2%?Tm?7v@}^3--IjUmv*AXJ88}SXC#T-yu{12^fWB2+K1#hg>`SJmoyV zc4sokx}(wFCa9XZVNW+F;FHBQb={};vo1l^m>1D|jHMsjAT}fg+7ybA6SQ4$E4|J< z&)`BgvZbOV>zk)V4u9fd_Hr&75sF3a-(y`guu9Xv5Z%rRd33-kI@B)~ zdDgeMeZqHsTm(B4dO5Pc&(VqPJvLkI-c`$Sv&L|7JIYXNX75ULo-RJ6?;rxqz29zF zZ4bPdu=&lww>4UoIksQi)`&1}ZJN3#?QHfXwJ6!hEoyBk>Yh@`FLiR#9n_*tt;s z%8ro`6|@S!07Wk^vhSCc?edNXq+lXmM*YCzrvvLU!RjBYKEs zyAEyi1;}wETfFfs8W|lfYO?~(I6StPbZv;1iMbnE@CWJL{QQ>F{lI?F)ZROoHT~sR zZ=xYOp3XR{gO~6Nx?I5V01}ki=xEX{u%;_q*F4L$V^}wJ;Olp>=H);L!4@yneD8fG zXTz&E`}!8G9sD%Af4`*&&!A0nEk}&=;%zjnJ zILyMVwGo-jmTPFI9^B1Vl9iuk5o&qst!j?vpHKJib+3J$OFLeM5A>l0<{T=;Ny zX5ya3059*|IX1@VkT`|ngwf;~lcHGEKmZ>0lYXeK?(jmSjTI7i*Ke+v3c}_hyX-k) z)p$iDTV|zjWA$;8ZwxCIhQ;MPRVw)7`Ll07vYD~IdD&upzxw-VG`x;u&!W@@2q8G) zXJ1+WHLk6SkEZn!-nQEOwf?Q#3+cv$T&FHMIc!$d%(j)chm<;J@0-5!jP676Kf}2w zy^sd>9HJ)W2ZBS}665hiwFoGJ^djTr<$WHhW&VXqF5ydE%_K|AoS0nW&R2R}FaCH^ zDGgfZeyMbxS0=&|k5wZC1hNw26N9SJH3Sxr&RETV!2Ev%`a>MkniQ$c0x1HCnlKR*@7WH`QH z5PUS@Ogy22RxQT$=gvK+r@Szsg5b_1k3(kCuS^OB2~7RE8_XbboeIi(O9idWQb7XR z|6A`m7aU(PzkzHPB9DJlLH#MB@KGc9!44IaWTwyiuPgm)^!|m2f32tgRvnRG)baru zy=f*t!e!qhdZw?#&GXb6QMw{Ms|Y^0^qdNE3Z{Zigc?rGkLzD}NuB(s=ESHV|FC*d zLB9dWulqsGHrdXkC{_3g34C%zbD_A4k$aGIeTHO&L7egq7st81f!+M$F>mZ8t$X^7e)+ObA||Ze(Ng&RLRM zw~wy-lA-D;_q~*E@L_;?>q|j?ApsK2{fQt@W)KY=yS79+2bed_J)wdCgZ4Ywl$?jn z$j43Xy}Tms?>ii)EcB0jgmwpa^^L8AnSQkpP4wZ4a8@eFyBd&A+0Fku{sT;j=P45i zo?noZ7rcFKY&jVjlLigrzvcMzqm8(~2Va*TUD{OgUCbFo-M8LmilUw4Mt%p=$H`zf z_c%-7PpF`79h|ilLLV=(qk5iPzBHqLc>X&XyWYJ9c}f$Q#D zcg@gTqkA0laC34MOqj^)(Hgapk41_=J)qTwElo{Ip7lRRh08fzl@xTt&j0qZOgpB-)$b&32axYt2b~N1R5&q2Y0?Fc& z=NI~D>E>o$m^3=KNntxrycmu`A>*}$(cH7`>e%YjKSwK8fY9D1x*iL))AanSNsrQn zuWmgRU!*S+Wnw~z?aCDVz7tQ%LDJAL8s3lc+f{d^%?(QnWr+%k3M=*6ycL_kt-j)E z4gKMA^z{5QpC1R^MdTs~x(->#yjzd&KPLF$$<1-U75EoC)lT|4a`Lwhx0ROl1L$R+ z{<)QMRnoD2R1RcuRO0=hfy5N-ao^YJ$Wuy;yt{=5&IjgE;siLE~ zU_bc?Dyx8gJHKBrb&D%1fv4W>lH`^BZw)mgVPZ6}b@{^|Q9&G(;pKDWB3%tzAg%j_ zdu-zloYho5zre`r{5|j6`$ZoNe*Ab6(Q?Uh`OXAL+=39WD>O(h{)GJCCj#%f({YM2 z0~bWPDF~C8fyPy51`j7O{ExCvdIcztZv?Xo-yS}p?}JW!Phmu!+;?#-c$5BIQ9!dI zrHl&lH~{2hcFl;Yu!nf&u95J`zHsrhE*fott#s}|DX(~HGNh5m!~DOhy}5nwlI>|& z$%>VEz|{@I-E{6hM#LL50UjYADZF&%RPlR#64V^maS0k@J6;JhXbNYU5T6lQG5iYZ zd#-4uZp90g29aJ_C88FqhWnbP1P{0LR}O zy*VYHYS(}0Z4zqoP5$Deq{W6Omh6k9K11%4NunriP+X9YMi*pOmn(?MQ2EK;4jz0S z!fTdr0*`NKniQXs9lPvV`6@&rxaL7!?3zr*X-k`E^u(7yxs+*R8Ju_D3eG=;bbhki z?jXUZ51FXyNZ-v1pFb9noNO@oGA^%hbNA}a0C6G})LU$sB>ddqNg@%sr$vK$J^3}# z^?={gi3z}$d$l?eS}-Qgd^Ufq&OS}ET^_{uu)ZG#Hz9egj!(lQqx3{bL+>*p^fuFx*Le!^6eNWjoj+ZW#{_o5g;2|jcz842C zsUUX+FtFM^NzSntZ&xp0vHJ_;Cm$MWE1pynz&>OC)ZofTa#{y3XO^lNZ(E2T@K+Ef zZ6|691ilXX#hprgNCkZ>fZeBpYHvDFK@*oNwzn(hJ!HIKlT^@|TwFCJ!ihGA-NVjQ z(0URW_icq{)3zkAR1itFkqV;N%uY-nO6?U8EgZwYfzPOn#`1^==}Nau2jw^l2wn`9 zt(TY>99s5FHoxlH&zk(z;BtxN?&}G=dRnX$eFvZgOL_{tG+X|-nhHAXPXQhsM8SV? z;o%e>J1U3@lJy>-oTDtY^2P;KivY^2n=vbxsx};I8Fl24yiE`!O7HDY!v4xMfBCu3 zn3O~RIHGD}P&g(Ag8m4uV@}ZJ^G5Kia0uu@VzgCN8#_t@e5z9S^7guKw(`CEY-Gl6Ez>S*EDA6G+?Qb;%Qgat}d{cLh@Dkwu0b4Y`w zCFB9$gD+p;u`@+J?)L6%?$Ga!^%3!+5|is1si*Y%?NbrX0FvkvJ`6t9P|0Bjl&lJx zYOeHV?1U7*U(NnmCAUadS8hKbc6yF8=D`Jmie0#CyD9iTNKb?Ne;lL+6$A=NfX-^) zpzuy;TlnapJed0+SH7*Qy9o2NGEqJ0+5F9dZViup>Qm3T)Q7* zRVMabhNIj_<>auo`QW&A-i>azTkN0nm$>g-lgvbJi2PjsuMNa6_NXckiqzOH$po|W z{@@we;Pk#v)x`(n!)Jzsg>R!PE;ERrXDa307lRFZoOwF9w!jR(&PrjKd&u^^soRP` zT2F?!Gc?6=s&aYd-n5VGKIh(n{AN`1P34!ykMHo`78M}!v`Z0csi3#kG&XB)1-(Ls z{QSK?rT&cV>E{s{iowq4$x$;EG`3!;`F#Sp=G#sSy|v(EcDtKen$n-%fT>geH5W8o z2i}tbe~bj4kCL>Jo|K70-C6RhH4fUPyKm+qQ8~w9RFDEfW_SPvfwzT)caPujdBVd= zxQ8jq2~^E}2CtCFGvBYnUp@_EWgm49%9xvK+TjR;J^79va+6 z1%1cK^StDK2O4+zje?4jXXq3czMDVAj0T(a3?7mwB9Rz-uaqndI$<6}IlNI_=i- zwf?5i>%uE+!_lt|?p+;?Gh)3i4%d5kzsz>g$I*sj21geyOOXp8=o05T^+rhOV?eylfLs4%EY+Kh#F9JLL$vxM8Ugk zNczN3jwoFzzz`iKgXtT6{gD=vbdNMFjF{YQG2%3Q*O{rWtSFz8ZpFt}E^$DSy zaoeGFkqXk%@#_LNZP1)223I&BS%lo3$E&tGqF4BuD&eJ7F*0+iZKGmW7WTf+D*0xn zGWbR)Zum(DKnhZ#5scxAb2P2ggF5IRK49^_3Ml!#&N%V%p0K&o>gx14O ziGpBg^=_D{y;GZI@hITJ@UHf&9#^FS9~kisfM zWQUGonqN02h1|r&Bm`+C`4UZQvbQHqUTsXo>rB;(iJ$IPzcRtiAm+ONA)KFNLr$WI zlbFaANDn_+pw=k$8sbsu-32*MG7GEv$pzzo=dhJMU0kF+`TRwCTkp8`P*r?a*86ik z!wZco#KlkVyi`83OW}QJ%a0CFcgHnNVpd{l4i*hP4IGi-N>F7C6%_Le!UiqrK7oF% z`x>!40hThI`Of~)l=-9rAur1RZe3hoA6%J@B%KEnGRRdVF*G6x(!jAtk5|W}q{x%x z3iYsZY+bFhgz!v}k_)Wz;^%s`8`IasztyiTb(20?@9$mEO!*jq=rSm^?DcL-DF z1P1yP0IAs?WO5!4E&m|*BeNvs+*a$;Hk@-jHp=DoNT}HDEwvlSt58zqPV0SsrId&G zobVY$?Iww*egM(X9Iwj;ZNuuP^sU5bx+m|7`aq@=pBYZ0t>;tKDgKMlFR; zt<((rl~Z=^#fMK0YM7yADg7%=PB}CH>H;@$*|Qj_g#C8+Pox0KY|9w0VT(PmJAwLn z>(F34Qn*dS@@R#Vu17A?xdL*Aq)faH?=pm-8^T%14b{5r01|y15q<%xb$4vv59Z=Z z&It>Hhj8!GNn1;OzfTO+R8p3B1DaNwn)et=QcwmJ!e9pPXoy56 zS>5c)H6H#epA1gWzs}=UfMn z7hHfSJQti7nqu5Mm1AYby4^}1S&5;{?K>dn9}Pdq&`9}yI7BKke#@~tbm>;awNA^s zFPTB7?pX5bNh1bmt`N7NEe*;Eq`%1J;p(K*c#$-GxN}Tv=IgZ@Af$wJZSq0R&FPYs zy7{NAeUtrvq6$-czokl>TV92IrGofi4)8cc-Do5P{odM11t%5j+ir%rOwv;wh~Vp!Ncfm@&1NSRgmPX@>0Uvd$J$JB#D;Uwa(*IU zwPreLhFLi_$cG&J@BGbwovG6JT_g}^Ya?W~k#G|bBbtWO{2N+|%O?epPJ@Z!&3edU z17PMxKSsd)`pmE6NXHq4N3{_;-6J=R4{{{TFP!VYbxYo|_7#4TU`;Mog#(wUpj}T~ zk1^nn4XwTa*bij;EY}wH6)frIm)MJKGp@HZbMik(^t&-~sXS>oZLoTm60cJMmcFac zovNpQ!Ti*J)5iP*(xgDjR_`+-UQit+U&`*Ns(y!jqAEueBUxDTOLYsNLGamk)4%Tr z7^--y$O;S5eP-8V&S$Fl*qT!PBL%ozvU`j_PsjkoFe|iT4)$k=y{rfLJBZLQ(3kiH z9>v0M$_E*@2TpZ%H&LM6CkpzUnKG?RRiEJyU2z%+o{_w8B|VT7cs;n=kHfw>8s@AM z{S}ksX7ZlLGj9f39Hz9Mck^i%$i?@NL-wkhJJU^v$F#AuBpN~&2%bQ5p&lA?egQh$ zR||b{Zdn|!izsjUi1L}Jk6q$gG^n|Sl=*8j;7!@s=849q2Ev5cd;#7NJG=WFKiZ2F z2!}wc^>9;xp35q@vsDTCL-KMKd%So(-)PZFX%F1^8-eR(hly&64$O(j$1A7;Oh+4T z2kZViTzCOW@X+P5gEHTraGR3*7^X&cnLB7TQ2Zw1kbgM;O2o~Ej)lDU>1}yGI%U%g z3nrb16N+%i-7Z|gZ2;ou6SDeM%6O(-8GCJJLwb@Z)61d#xl;V?rB+l{?$xNckj4C$ zRmX$|a-^>8PcXN()Mpa!xaue;pw!b@14!;q_M9v=C6vmVYpod{OaGKTUqHdr<&J!* z1)W{_`s?mqQD{uPVLauB2pa-3+6iHXa_yM4Ogx@=mSAFC+t!+V66%(G^^BQ6S7E?A zV%xYSyRJEt465`~z3)i|Y?5e0i*jTp;k$k~KMLa4$*~tM1=X7ZSfU)@y_BoC;PJ&( zryAFkj|>Qx?Bf?k*}Wj|%#w;eDrGrTULxHDu?<3KeuSdsn{C2Ts+g|x(Nnc5%YqSIQQ2OoFNUo{iU=xMT4A*+{%F7q}h*PXOdS(@+XAy zzKs094+w4mQm0Pl8a)k1ClAx|Rd;ETWgt-uJ}!%kp`6}D0@Go_`a+{$Y=d?E|6@lf z|L4Ujwzj1=!n%iRk5WjAqq{Ws<5qn)7!a$Y<<{=QdxR*1E5A&%FVfbcmI6i9+3>ER z@;;Aa$_F?m8UD!cL?Z7T%~ul6q%jEv6uwP@0WDW&i{T(~&cpHLCz|mZh^KYCP(&2O z4KY95`C?b(G7j=mTfM+5xaI27+)t~fqkfwQdvC8zXNtag`og;DuD;~KmtF4vCkNhG zVw-JEN}5Id-t?n_@`tYr=h861L7n+0URG7S*+MH#tlv7$^S=M%m`Sne+tPmqo+CK_ zqOs->Du~-QT!acrA-htLa6+Qx_7GThBmEE4SX^{4yS_l z_$o@OTzgh%D*7{g_JA@T-}>Uoxx4ysK3YQOE2Q_lH>A!v3U(PS1z1-Ad9*%z1!8*n zgAjj&o~XDy^;IcqZ1QBNcVM}9BeRY5=9v^e*^d>8zVCA&^+O{Qjk#iuP2Njf+k%5u zhOyrm5-!DEdRSFhCKgb0F~;10Llua`?GQG}`7lGGM)(MlQ&rdsS| z`j^iYVek7*4dabIH`WX48(Sdmo<+fbwU=+FiYIc$^1%}2;rFJjd%<8pZ&+79OTdZ`g8k; zWGKDM`_J@)!^D;5s^eDTZSp)Sq5TOg(P7}1gg#t}LNmJ&F_ifgL2Wsl7REj1ci7Ea zcyK&S3=262Bsk!zV|*HOcG{BIEKILRL`?kb7-dk>@Z4vgb$NH|^4n=*7f~D-ScRle zL2l0U&>ljWPnx@?urvrk^=(X?p*X)OJ>R-5@_}`gt z`2V7BnfH+tLoMXV;Xg>*s=St1$XXzc2&|U*o3wrK?AKj=QOLhNr0}1wCF`MJ=UVV? zR|$;fqIGF;oH-5Cz|C4T&S)#sIXT8PEbOR<#M|t{4jRs93EQZAt`n=f_UK{B_RybW zO!J-sZWde82j_taDqf71-8obK@Ljq&81yLc22xK;gdbB4 zNLugOV-(_oS9qS8u`Wqgmh2n?2s0zqTw@c#vsS_B8+kL|_LDv{S!Wxhy2e=!!#dFq zH{+1#9Ov56_;yGs5OCbXYgMzYEAa&%G3;8gtrntYx3qkqyWQ{Md(Y(j?15rD>yMkF_ z#*{>>AkJQ~fr-Z7)|Q}Oau{sl9DXeMVLN1~A1!F>Bt}S4Kky}Xs)ouUxO9d4R>grp z`L87kv5(9YpVbGQ`}%01?P+AldxPb`<`NwlNI#gDavrAhRlqN${cfR0$XNm7OH&Fi zO@Ts*LzPX27L8ea^keCw&r}-Ea=g*zphXv7$gvdRZ^)i-o(>t2xH7mFgRfx(bZw3Jqh!Bw#lsm$GfYzIJN*z5FE- z{yqS4_0Mys7uG6pkAwO3Ti;>NF=KLRBk!poFZ=L4mW3AN^UhIzZTI-_qq7`&Boo?Q z&ykZ!rf9@zfP=!>wsd8oGhoH^qvKD3nWADZD=;dcVb)WaTsdX!rm^;L!eHW^xWe$E z{7Mas1C8V$Y2uO*Xg^l*@t-IM89(1Cn&Ecnpm!W^QTkc3Rk%B z!0H7cMDl+}(BltF>l)D1rDs z=(LF7y|t+G*8*zSBABqskv7?zd*^ZXMq?}1wRnT1Qe%SOb59@kA}{fF^E##2grU-q z_a9_<*wUZ8x$wp|YJBgV^*1;N@(D+D-c{gL8A%(@-G_)#@DUx~Xt3YAu@ZLVMd)5L zJZ-fgX87iH|Dg;Q>jzHf>r%alm;mS?Nz)X5$M4+hBlZmWPs9h;)qM}upT8f_SeVQf zvSS!W-F4Q4ZW4+B9kiL?HiGT9u-zh%W;!80P3fK#_qp_`{`CEf(GNrFu{e7djzlZk z!z(Bmj9=g1aDo;X&iooYkeKjk^d{>lJ= zHGk!-+H|$=NJl=yC$`6e*`8`G^L#>?Po#x5(%(D$)|82#)|G&1jLjI%{3ff7JZz5G z`+j`afMhu}VIR}_0#d`rkRbQ$nPm6A6lo1Xh{&9ISOujvt>?&u|jlG^LkI`q`ww_C@HBLBK`14bJ4i=AuXQ zFb_bh4DOYy)t9Y0KsYCL@9+TaSNqbKLgVUSReE4u4Zcs`>~L5 z$MT0?<;xO41rFKuqQQv^Xi`{ zF=t5T6NUXxP0H5>hVoqHR|nB<+2J&}h{&78Z1xIx%ohC^QQz|qtE~m+^lG*D5Rr&| z@=8vLicN@?m&_`HR^8XM*;Nhl?9ht5{Wa2NR-2K_D5O~8yT6gL+SoAXFwbFv&$}pH zdsthS~whVMQ$IQH-Tm<`jb!z|rW$40OibEJ^YdUIIONqIjE;h(wP&LM zDMG;*MU*nWd=X&7#LAXL_Lx_rf=-onyS-g2S03R06e(7y-((_*=DKd4IQD7I5qy8# zSqCsARFDzcw6)EYjvY}_#_UYG1pCTkV*Q4spAD17l?Q7J$TP6gHET;({4v_9tYRL3 zo8qe?{o$oozE(EarMHb}ei?c{rs2-O&KjAm;ryUg$19%HIg3OWJF(ZdP3PnGa|%}m zn7)!Di?us0H8iV7oyqfA{1{Et`FKb%%6ajv#XoU&PUIZ9Fr3eO`IKKQMRK}fgx*+v zmWR{P(JMH`TkHDzO+)Q~hDW+e<+q<|mhLZ#H{Y-@b6wf0mZv=@1?PY&SmVeUh2vof zPU@zF&DQ2}Q>O8Rsr*!VO0)^}c+4W*<)MbSW$^nI<$6yHznq1_1KaDM1pFvq;(&I?~eC6L^` zOj)>{L0LNBmv`lozGWo%o$rT$&d}VTxMigwtuiL+7g)e+nHztr#?z`*KPh*&HEL<8 z-JC|)4bhwqJH1O>Timu|GPS6}Jn4G2ylQ>e4t5kZN_d6~k8{Cl9q@V5s$Y{!MAC!^ znQzPl7Bw6f=AFG{^&*XXN%49*`Y#^S{MM*uig**wCnoM$+3$owtBvJ;twFmD8(ZzZ z)Jta^-;{jkqhmdqNVeiN4AXyJ5=~Ko3FDIsBvUaQJRYdZMXQZHbUiZSInSc&anapx zEQ5b)lV8kc0B}MLa2H#hU>DOI*?LYsrNpCJF>}?g>pe^i+{@DL_^CKjcE#P)s2a`VqYe?xfoIr99`28FZ!BLR zm$oxkP)60A8&cx3RFc@owzcY&Ouov>yEQw@bzDEth~*m#uWQy-4Ris_tJwxnhuAp+U86Q?d$;8*P(&{fP<>iL{hlVs-s|leAMdwJkJe)linw;E1s1>gz&1$vq`-}v<3IIsy2|jr6$LsDI~G?ObCb4fybPIlLRyBt?BOB!mtp1=s*fZ z6UxzrI1>bp)1*B|`B|bPq14+-jd1M0X&!SYc3A37XVW@Z+TFY>$jau96qHN83SQ|%daa6 zM4FCeU>-q}^Fz2xgAzOfI=tm?WIFafTU4I1lA|RQXc08ZaU-i_J6vI0u1fXGC&Zn2 z#~TcxUy8L{q4&Qi$>d!qzA3`U;}SR}T`k=K9O2YWrZ;hvl2sknWy;)8y}e24LgDy( z`rVoT+ z&e{#=;oaIwJVQ_gv7amV_X{HIV_X|#Z}0Md69--3GP_`#y!lxF`JG(+Dmu7Uq(Ci| zcB?;CULPr-gbkMZ%6%7FA6CI?+t!C&^E79{*c4O(dNk&=aZZNsdOZ)1)R57tL% zn=N+Nt(E=eVoe%ne?DKWlxSe&4|Xe=f-NtZ-VVO-F$9~gG9Yj?fIQQ9EyyGk3>l3Q zH`5ej(@ar3C80ek+YtJ4@%2^oG{-CF2KOF#@-p*eyXi-->=$0@n$HBH_A|M6t$BIq zEYDayC{)^$63nvRlBO-j&~@$sCHiTsz z^$DFXeV5jJj}&RXXNih!)Q^eyKQp6*_kdqD%zd1~4v3l8%x+Bis0t?JBy{; z$8qA~D()emz~74yUfm0eKm-TN0u*7CX4(4E@upjIO-`KXqa%g{KA-PVx=%Y@{WSX2 zd77^m<_+ZEb%4Lty$H}_&nP=U*&HT+f7xqdu{Uc;UNhW~Ut4r_>tA0FoC>&B)m`ZF zccR{*7ksEet9GAFM^a+sp8fu=M+J%Hu8^P8gxd<3q%ZjtfBDqEJw*7QGB=zFSTo=@ z93zaRDc0NeO%(*s@Lu_0S*BIbLsIvv_mU*vD=hTa7-l=2Pg6m(3RN(Sk5W*r zTji(K@@}rd;%SMeefP`|YY#aGt-3DSk74@SY`G?u5IVpt!FHNf_^ptrd!>c)T?shu z$vBZu^1qb%r9Rci_rd!X#dS`U&FKDo0^{15Q%>Aizj+8D6-db6K7tldI7hV1(|W>1 z#&$0@e{IQD4?AyeKl41d()?rQ8D6iB#g~B*W?MeheJfGCsHK?bCor?Zkut9uiRtuD zPTiA>U6&4wE+uNX8<@RUieNotml>szwpNrM6k(iIhb#^W)f=EvuB@JvtlGM{3j`P z;fYO_(vZm-IP(?4b0S<9rah}|D32)IRVFN8inX1*>HmHKD> zIT0K_fvWCxW?I?NoXPah2Q2R6exES5y%oJU@iAUwm1oC2OVZtz)l6bQ`o^B#o3F^O z(YcD=Ji0Ut8<6$Pz8cUI!=IaO|2RsBQ*~ovN`T31*1Y@mtbC5;f9tqy2GkbRL3N6h})%H-z1A zRCkD9=`O>3y))%CtNBdtQ)>psQQX8R+s5p@y1{sXpSj*IB9agdKvv;G(45XZT^z%U z@S-4e8!;hcqA{y5{>Q#nPH>F>v-kkX*f-;fi7!n=8h`6w$Tj#a5Mj8XPRn0EK0vu* zdHWAIfE|0}IC@+q41Q}SV`BO6R{XLI-|G1;A+|@ww(4=(Eo)gJ2A07FES6j0tl67NTPZae<#!=mC)-8XE zi29Uo2!3ri78%Ej;DBSmU+aOi!k;q=YV|5(i=J;i(Nz~Y7ru*VFo6#)as@`d%HAUi z0EZkY*#pT61&y-}G&+l>qq+^fjx|R{$|5XICk{w_vKxH6_a{~G$KAEu&sx?$D=%D0 z)ZqMc^D$A76c*Xd_R)T%P``LfU_a%vhm&x}l>5{kx5|NzTXSf0eZ0T#&LtJaR@3!5 zb_3H;w<4l4Fx#JfkPP$3j%Z!4oz^zRFpfO~D%V5PYg?%xlQXwQea_4JO2*b-ViH#$ z?vy&XA|1phEp|wMj~u0|Ir<5j&~=q|hYG4G3C~i_c&ZB|PC5vF)!xde=~1bXny*=( z=j%O_deoRB^lB%Mnf8MjAs921CM~hfQ~qG;mu)-k$$op2>OJpR$!71tECIDTd$(jm z$NsA;9+rv^IQwOOCC7))=nbaC>&l0ZuAC#8;%SU4HYU<_LaJ_t1cpS*XPkJ7<}F*j zHR8hRyfGHXbaP9brWegi$971OU&EZMU^yaLA?@<}I)XeWNd(*mEqK#!2drO8`i(rsIcNl@;GMghSNc zW+!3XW(+!l ztu5hwu8NPopX75BR53$Y`<0iSTo*n(uJ}M>3k0#uy$Bkh`8xPvYGVy-VKVmPFrAXd zjncYXvIUoQAJyN^4@yn*lnCkP(c>RwLOM#9?C}MN9U1QsZUDsyF3F~*G@~{gc{J%W z>>+A>Z9=zM03~kQz_PZh;Xx?)(|J0puH{-4>k&Z`*eivK_3F}%SF0Sb1K~!p3M!SX zI(M)qQ%?3yY-Rodgr}p7^;N;$3=5C{bn$hOy*{OQ^rV7?NV4SI-?_|aj>Hb$?X6ak z{8g!`N7)`hmxHX0g4lwhiam=W=KkbFW6R$U{=gck9?3QDTHtefozBhvTH)%!eC0Vb zJJpA7JN<0F_$_L~qmV1C4xI!24n@&j`J9-aBUKEykuEHz)k$T+Jr!QHmeBaR`Qdv2 z1S473FePcP-st_(YW{IU-eueZch=3_D>j$Kf@zf`qq;ie)Q*cJlgV(IZOx_XnB7Ka zk*ya7xg~}|6K34+W-d9a@Y~Jv8Q2zFxvONnR@zxT!Fu^}1N&t}j-C5%=xU`pAr%S4 zl<@_HvG4T$#Cm(K&B)6YHD(Uk3<;_N?WDt;e=(AOVskECdh_$}eB;w4|0&9kmAc=@ zUDa{nV)&BS$92=;^Ti$lzBw=MHy&1{Ka_L#WD}j=REqA_@&$)7#}n1!9rkCySH6yp zAZhnhXWa)E*m35QBV8oNkP&#z(L3iHmdsStc|v#;#h-kR^Se}MZ0-L59XV}g=bQ|w z4M`vcRs+qB0NlUi=Up!g!0EuOA>LMY#&FDTbtE}Bp677-?PEnH=8NM2AUfpjt^E5g zgDI)ue3a4b=t!atkb^O(_2bEUj*TocQaFLN)_q1r_$aAN^!VB~3xDUisyrzE)*FM2 zM=(+@>VG0#0XW?yiqlr(o(Oi^Re0q2O!10b$YxAF-1aPLeswn;eI~V5Tno)3=UhK! zUOf5bn&jtj9Vmhjh~MlzNT7mvX+K=SVLYLNWOww^<$k>#B56~#>+_2!V@(C!u#B3y zQJ%xAG*H{Rc0R=ouq0jtHaigwj|X~9VfJ2j_rpb}e=o?4m;Xq+p=z^!FUghQDrl_! zI)r$m>^l2|0g4R%lvBFrA}w|VC&ZG|C|6*&@y$v5+M+5ZBg$Bw+#(yZkO~v&*6|;C z2VW~)Z#!HIda$iMh*y_-<$MPw59pKvysON;kl2v^={=HdNXh8q^+!MAydQJ7clh4D zE_aFNkL@dFDdzYSuJ}xK@3Z<&n;SEg#EUTfj>!IS)LVC)keHS$axcmyfL}H z&uMlhegrquwu@<=Tr~mLuY7z9#yb;ifz8#F6g&601{1P82a~73Mr8TCZQMxnJbF?< zEe}%P=h1EJn4TD*g1(ab9)v&9*N6PAJwQKc7=gse-N|sHe1o_G>7~#P2j4#p!_|$? zpQbDYUitIw-8H?)m}~s&t2Fs#0h9h0*1Za6?150bOcOkByeh+_Dt}S*!frNcNBquP zx%Og>|BJo%j%spi`~0yY(o}klN>zGCS`?&-7_rbH(g_HNNRyDD^cq0{0Rg3mN|PFT z=uxVGv``bev;+_$2|2&pGtcu|^LS?7bKY6c%&eI?f5f#!OzwMU?|tv zxP0!nmFNSzY=+F724cS+^b8&RW}QI|y0WpXtg$@Z%qqEd`GNCIX_%#FYyml8i&@+K#jyR5WYW~Lv2NFQ z<&nqiY77Tbq%DjDs&GI$zZ{#OB@+4B5|S`A4*0^# z$|b_tfM0j<)w+23VY*5B`!h@k?93U(8B_)QDoN5Wb>C?;>J3R=-rYf3UCQBrg(h|~J^mYX#nQL$2_AE18CNy@=DB=- z@#V7i6-u6b&PP$>1r{~O^i~pN&5%SP=w%lI=Z4EoTtsR=-dLt>H z&fuowwYwxt(>CJM%dPbWA}*hG!m58JG*+}gD_r6fXT~Z3*J*>1bb9*qd#94-a?8{p z?)+h~+VnH|xn>ifSG7OnWxZb=fx4R*_LjX9+CG9smd{}OPwT^q$6*NeEZSzvZL;!K z*W!j>Wrd7{ysZ^xT;6uokC>~^2I+1MkKK46}|v^{t59O)W#La7i4TT7C?3RV%aBUR(; zXYlKSM#g$4a?w!mnop$%f7H67L59<9bnsnb_L|&WuR1<5iYi11thAakx z_qWCQ^LrJMx^`-xwskp8SXxdW5%GD}aPkMZ4O1o--5@~{G9Y8@ydC_340yNMh;*^^ zhNno`bK_x=#KgJy#1x4M-+P}1a^Axu9?G`uWW{9pzx!eGL*+H1bEeXGCZrM)fw-8_ zHZr2cO+-b*6=1#|zTT2(`Bf81?_Ob#`?0*D9g}ayz6)KVQ@1*Z){T}W>)#D~&Z=;Dd<^MNn+jZt!`NlVpdY{DU5xiGn8MOWQB8sm zUZscaKg86bd^Ez{)fcLyyfc>+j>SEr52;K)6{E2NLU(8 zo_q^?b!2DC#rWfpr(Ur}qRq;TeYypsB|AFJLcnoyAmw`3p~+*x-n!C$T6Yji(}>pW zD%RLFDntyW)X2MPGE9~6eT}_T|EzPnH`wb@$w#cynTgA1Lrs^4nxHKkSj-yfOQ70z8w=6hR0JB z;cTSMmi|zcnd1${f++(Nnp-P-BexCueFf%+dUy%SPr(U zG!j!%XR~>_U%SeYku8?!2&v6Sm)<71Q{rzaqI&9By;wJLaZp!hsdG}D55T6tbXTwD ze@D*U1p^fxDDk@6eq=(i)V;4>YdaI7>7#eEO)N$s7Iy@mTUkY!=se*)a_*#o@I9B# z)LmWj=ilf~3fUfHilT}0yDGfTnyN=dYF|!IzZrhhBoW9pZZK_UW@;x9aW6Kc)^0yg zmw#iAMb{ma@f+P~z(tu5iEWZ2nYG&JTp!xmJmb!*J6n<9SN;k&wzBSiKDr~n8SNuy z+T&fJaW8)P2J0cf2FXZ{$AegrP617GR~yqb4iyGiikhX|OdZ|ZQ<3|`*qnFu{7VU0 zz9*kf>Wh6x#2^MuKh|<=AdVrvAWt-%rK$~jH8BSG*?`-#&XTgjH577s?MM8FY;=^9 z3K^BcRy{p>m~@QJr5JQMcw5hcN*>LO6=17p_^LL~eDgm&xr{4me79QtILxxKqp|n7 zo21I2asIa6ZMY@G)Y7^pnVW)N8u!lNt5Z-nPL%& zrED;@sY=L0V!7qm2L^lP&#tY8pIM``=AY(Cvp)bEiof4Y*pmRBol7=*Ymsw7$ftFn za7FK2cY$?tLoYZVx1}^RHI{sZ#bf4XXR1#(D#bKiTl!NJhH;2RhSGS8nq#r zH>B2bzA8?fIM{?= z7@hSMv6!;yPU@1&9)R)$r1!Vjo*ITby~{Q9%CqPXx>zvnh}K>^9`N}{3|?1+AlDvnOB%jR~&lwlHB*V&MB6ggPX8=KWSM5BvvU4BQ!n6U%9 z_r(m=_4G^aK_|lD%aJM9AW=&sAfw~L+$N9Co0a~+xlDz2w53$hAjIKVR;HcEo6{+1<30KM$mink z{6g!6ICfojN3o^*oRzFpfl1_6IcmKW1>KQy1(DTj033jmbRf&8EzA=z1MMO}TTsfB z>P%FAQW}t9JF@7y@Y4DU^IFs{j5qLF8c6l!nZu;2jP(7^hFFUG+~@(LB|VL01N_56 z|6e~Mf9l&Um|(qbAlJYC{MV0`U`_iAzs1So_;{UT9y$RP#4KBW0TcZJgGpBx_?J;O zzm&LIX_okh!4{|C$lrmmXygfC^sYzIOik`B>X!`I>K;^)R%zkIM}Xv;KZshC`>(g8 z8~XRP{XK4f&$pk;`~SSPkl{Xu0<9o~2OmKMm(zn^s13KLq->kJ$=k|io=ur!NwT!U zU(^1LPS#odqg>w=U`HqgaAy&~Q;_bjzBvB1d^QUC*YcX|KTHMx0I2=>({dgP?9k7= z_y9=8ky`-7B~W72{S(F&^yBQb%5QWZkLUkJm$zkBGVsMlJBH?~#SOP7R}sLWGnHoR zE#UUzpu6NZK+JHH{KPId;E>GlBX`!dqYbf;>R=Ieo&{Gz!u+R>yu^=po;-syQ7y@} zL`!UI5}cj9KtRUaf}4{0=D?ipZ8wLxZqfRN6?@fi1nljP=5x&V1POssBi!Tm_{%!y zQ$EZyW)Ev}khy#)cLVy{5lZB91pzA9hco&`)Waljw6DRsOjuJe)wIqCXM6p0^!A}7 z2mZ)c6?2V&$hB^FQj;cRSAVp@kQ9nlqtFIGtiBBJJLw7U1XVZqbkJYVWwol#8LT^_ z6Q^!n)e(B%Q?#MN_DmY7U%jV1`YblqkkfoZ)$!bmxrE&5S`R(~S4e{{Vci{1ds1vZ zz1qaj*;@$vVlA9%dj7l7L`Kw$)Yv{7wB|CVbBQYfp#*hXiXWx2ewL6^fEO zSP&sVRU&y-5@EQ}R?x}ndjH^4U)L4at%I|67fK6s_|4c#KaJixce)|#UJG61Cob^2 zlM+8h>d5W@rQlQrnXi@yx9 zH?+$mzgW4n#0SHBptW9#1&~Ne1&Z?3wG=R1o&<`c9xJud7Z{C(Unw=$eGl8x50omN z_ct*-m$GQ27abiCThz=PH+8)xy#K4)T+=z=&dpkpN8D!4(1gC-T;4w(?k=+NCivlm z9U2|x8OXmKep4QjkCX>-H7O$oW-21vASeU}8AF)iG$a8=+U98m5;%-%luwTKqN*SZ zV0(Zw9S(PhD+g&x#coSC zs_QI@JE*B9!u~8V24@tdwaez;%*B)#YcK6&!u&muFplpT(dW`Qui6a&QW%hlsl<;c zQb8v&23fWl-C&$g>j86U=#zY_pdr&jq`Z{$&H~OF#YPu>&O*E3!&u%tImps==E`dy zKRNK7a(ETbIClh4`*xFkX2sT-2{O^ushEn5MMurt7)0D_DrIdXOj&IM4hl9=35 zAK$3w%n1B2N%psS+S=0_C^)-aTvt(9-B&a($GlKcD1Ev1K-nF{20sGeD?rQHj7piN zj9#Y$5~jB{uYdGwAH4~qnc-~cy}2?u=OzNamwdy#D1CY+fCA9fD<~2$TQzbl!Dhr1 z%3b*qZk0QQg}q;`GmZbSGLrJVYOvja>y$nyO;OM~q07R?pP$x?Y?0J}k?1=?<*%wi zXTDQ5f6hjde=J;uv+#rA64V;!y5BLCUtw+dWYOSUJjbiJYWar`4aF@E`-AnCb7G!^ zvzuH#_CMIP1v z6Ee#C4D^isk=XkzOa*vt9>dMLexm6Rah9~IHvl>vFFipq&pj6%iKAlFkIUbrQr}Dr z#pDt(022Ep;)GlJNG;JFKN`^>7D$lQE7VHNx3VyNocFxiFG5LP+B~z!;IkNyC>j8T z0l1_u-9U(v1cWFlkC67%pCL->&k#if2vHAE8RbtnQAork${?ql|?8t@; z@!J&9shm^XMb)n<8qOT2Ibz*@+>=(0GnLtu0YVd=N37H{*2t|s)EX2BP2`tBWZ|Eo zNhU}ZlZbjl>jp+5LTRPpE*=w!;2HXE6mOxl;w4p?VO|hys=5&E#T0wW;bB?tMTUyS zV~NeG&i%Jb;hf}4gqID5^wCtYT(=8z;^(VIN4~W(L=+x9;gF!-yNvh}6?d1@rsd8v zRi(^>SRfRLumM7Wqp2WjMJ|O4h;Eqb=xGen;2$pfJu>rwmb4b+$1S)rn4Sy3qC|$_ zmZ6y-%JJ?sy*259OOc<)7sEy1J)T&e4geZd$`s($f&f(zvqLK>9%9#qa?GV9*9Znu zv(d*ngyQM$+~q%Zlde>Y*75U*ts@PDCQpq}G>d^>FJzHx>k{%P4G5IW3)*aq+Ijoi zFcDcCUrMMJOewfY90CQqzaMwzfV^?t`+XWnxLoUQv~b*W3)|BNF&Kwzx&Xk#*qTL8 zhRhxaT_3*hG9=@1e@9*1uC~0+30AzQ8^v%gIr)0xN1(aFmFAMYU+()~zn$10;nakn zmYE7r^JW;Qtw_dh5HT{c;ZRY)8)5feeceGRkG%AS(EI7W@uzN>Og4=(9DV)`IERf7 z(HKhK!sWgVTtY#fxxR93EEc6@m3I9I|ev+kMG$k}vg1*m-{4#7e~M>kx+cW2WF z=v*09bfxlXMY<~|OV&*-6t7O5co}H&>A95x|5c-gqJ<}Yn}wKPuHp~NXZgmIHchWH zkr;}Xe&UO#Ofk0Z>%N#~tH`+VWgcA~p*$qHan#;i>f~!#-Lo;WBy5$rUM;Dhj|mGb53ql1!_R+lzPWSpM1POH0SEpF(g2c|jPJ#Ogam!vP`Q_pE{C|Z;K>yr6p zyr94m`aLZEb%8JcVeWa!P3>y>#cav^$y-V-as{Joa)2Dbzpj#BW=mlBjKipF>G?l= z&M$L3XWGtx>^n~4)1MD2`lZd^SNPxBC;lG8|7y4XzkMEV$wY&npD>=pH< z$e+P)%t`T_kiYy|JPVL@`Zj3|#lMqv3VyNFzZB5?9hLGAw9cQOooqK2)zvMe7e1RO zzM3mxcW&}U13rTzKE&;2=$YJ#ug6gB#(Le?hjQhxiycZ^^?ELXp2IhV)MFG9I}fez zIQ2I8`)yhFb{XXJ35MMpUBrZdok2L>2_v!x5ry4e)@jXV`X2S&+*kcVf%_`SxxBc@ zc`C;o-~4(dFz1!4dTL}QY?9H+Y;Bc&ljB{>s^!Q z*~6vb!d((X<7LF3q}tYyxuk1hplGSJxdwN$EF}?W;8wHL^NV@T`q!NtE-o!xD(!=g z`OiW+1gx~lcS-c^kNuwKEYq0P)<~auUbvyl-B=Y5Uz&3@ak%>VAsjn-_`xOY&LgZRM)yV-FK1z&H)a{V9|?~J61tFeqlAEqDXh6=m5s)~hJ#oexI z&%@Pzj|^=Rf@_f@nLDr{N>l3A2?NyH2|(Vxe02#d@p8O6iQZ|m_~j-!MGnQhIhze-1=zE8{esJwN~US>z>UOX zucj5fIFX)MZ*Rd8DHl=0ouQKjF9r_DXKrj?WSIwm%s z_T!n6`ooX9bsHN}NcZQf(Fr>i8&dAw`rZZFzvcJQe>i2jBBTUAP z;2V2J&u>N;#qtGwX4z&cyeQ5i-SzsgLd=dj6oot@L)D^5m66_tD<`uP#y4-9pxu36 zz4zvMruBt##iO?GIM6=}ta}inB}3N7FSTU~wWvje7r4_{zG&zc*i3l@o=@4n8*Mt( zTFITvF)Ghv_T-a3r3xDW-DM>Y1Q9OyZbt1{8n3A|i4#Yve7t;vq+f4YE)Q6DJV;Wv zXinH-c-{?_6#a7N8M||>-K6#48X|cG%%{b)N)tj8{lW?BoO@>V(PB?K8Og%6DHnv; zB=W8;j9Z=;K6?11KwE;_6;k%>w(^HULL+zPi6ie>(JizH1{~9Gbl{EJxh1TISsOz6 zAQ|Hd=AwO3gT{*v?+g<=V+mF^wtcE4wqtE}N40J~krJxB=wgl8OrMXuRakYod69L^ zhtvff@4rE2ULYg7peF&#{fJt8_(DhhH;iMAy!{%Z%@+kB&*@UR?HBwG>DFZ%S}tP; z$DYq2TU;Mem~Ek4%dxNzg-S25H$(Ivejv!(dypRpB(n@YXlHp_4HqFP;IXKU()(}* z0<(%$w(-4G?=hQ>ha+q4A;PCC*o6!4DXW35kyB?k*N}w)5P~$oIAw>W-wVAFX_@YB zvAHn3$hH5fdQh@kapYtCOx^RqyVjgP{5>6PpHRf9%s^i5w#mq&Dc@qnnUkNH7=Y+$ zZ|fVzDcM%DTY8ky36O;HVex z@$l{V^%V5Ua5R&A^}xpjw|~r^$Q3YW6Nmfm$R0p{uFM$oBxD5$Ki%cwG%xmEQsa2Y zV?S9x_Mn!h(@h_+!8WNYeibH(rc`eMs5dv^w_B&;?agIyM?701eGV-K_dHYRMR)}a z?Fx|V=MEU}l5`tKV(}>U)%1g@p$Q8^$!gB@8wCX=nL+F>pSAZC&PUr&t4tH`#Mkti z0f^qsxtazB!olGovvT(oOnGGM#~-qc`7Ot{(cN@FL+BMIeIpWIM?ML#HKUNev`x zzM)!|mw6~lxrrrvWL>#{a*P*Lp?iHWxx+!+j6^yDedHKNs9=& zcvRWv`gZl}J!!m&t?+I7q_#z2Et>LN`mMNI1M!A4cU)xFvuE#;d}kuPG&DyZO zlZI#GRbI$*Omi*pXALh4N|QrpL6JmV-??5N$iVrU>GMI9m+Q&YvfAo2o-4RZs>_#@ zez*|4#;oRKq8Xc^ya4zwC zyk2GF-@qWPW6Qgie))v~LszQMBd0#wN#f$`L|7M~37cO<26ZGty-t8htPMW(%dt;`r^ylIs?J4_ku5DPiNLH>Bb2Srb;*))?epF)A zlyW_MT-Y=_1mg&e!7#&p@d8%(s-_Hlkg?*pZc#T&h4(wgRX%4wQ3!4w77l z4bqjw7G_TZ+dqGQ*DiKl!EbaIkGD9_I*#^c^CO+X zZ1CIUTmp*ULMz?lJ2EnLn!SQcmpWF(nC9sFf}qTJ%B;mnWFK$*lS*KZidIXA*ll9U z)~!kh1MN+84aV~mE+|Q{nOKbr?CQ`y=-R{pj6bpD!{OX}#}~#Z+wB-G1RGh-GrLnz zeDG0nd6v3WXkZZ2VV(tul2GtQz0KUY;TsIL`W&ACu;3+%(p-q&nomZuxs7{I8s0(n^c0$dP=wpA>QRq2k&kar95V-kcpux^2;3ymR3z!~355G(HAhns1BMI~a--Eo^VQPxJne+E| zM{mx+Qu>*Snd_PzT$lWqY1NvcLa^q~-F%*0{+e8^&`NY$DZnx(fm$=&Z7j0hNoGkI_qyGSGDgbEa+q7gYQ82l5WmIiFJ+)>ir!IPf zU=o)aCg*!ZC@HrX&N0_Nu1)~fBGsEP;ch_H6buLc#tyTbbL)hqnwN#%;Ot1@;9Src zk^QK%81iP~(xkV`ENU%$4izyYz}7h}dde+@*RQzfn=)^#+urd9>FA7SyLw|+ozy~%CKNUaD z-Rq!FdX8tBz5qF*ODGnoLZ_{dLb$$Uk~a@HoFs;)0sXiS9^df7D03raZtbOu>P`*NfjawWmdApAe@ zdD|>6QT3mt=9l{EJ~GfsvoXE=W#8J;cD1sId+Q)#`CbbzI3Dg^1Z(2p#n)I_1smO} zU_Mu!nCp?Guh1bX%P_W%KC8^4>%T-mwTTRse2*Y;rbtPiMc374uO|jRXz^3IA{<|T zGAY5qA!Kf25hD%=e;iN=AbKq>!xC5-8QHF)oOOJJs`<{UUwH1b#l}XdX^ngBlSgKPPTLctDYcr7OLJQ(1O{9bcjMPaI#L*4tFzUQ&PTbK@)G zJXLF8p()aI^wFx>kjPWUj`VNB%3D(opA2hyuq1FnNBq?vFej1e%q zroRupJ>WvpoQd|3Mpl)aO_?eca&+zesSi`zkc$9>@3C|Va;8W()-k|NC#WTEOps!` zRr&FYZ>D5Nk=3O{(TrPV=sJ{f&8--n6Isg&PurrNAF8{v)k#U%s>Tj$$sD}a5+Eyd zaMD0uH`jUuZ79&GgX-}!EtO1Ts3ddPm~^eJt>0@F!!%8P zl%H2_6P%xKbthrze)YgHXLH9hOi72hrE0?cqDqCnLCLmRM?%~89_!@?yTIN~tnBiJ zJuX6zhZFe5FV60 z)pB^&qOY`zZk-8J1EA^rR9(`s$`rp5gydI`&C2EVuh~M~6%q9E*eZ6p6!|ez^$3Qu zNrzuJ48*Gp3&zf3V!@1B!q$`HK($XfxzyP4P>r$LF5lZIxwBrU)j2-X^I)$z=ac;L zTJeNRqF^Z@UUbwtIp^xo+r|j>YS<_9=I~dSq|J}1`56X_(>+ z8_bNiYKPIs!--=}##@mk%l=bhg!HG|i%f@(1@=j7SKI_(&BA~^xJ^(1z~V3i%11whVj?X+h6^53fW!bS*O^VJGc|2*xggBoijB5A0 z;p-l&U+x%gzeQ_L>1Tf{S9|_oUnY4AozGvkp>)AdYmr#mDHDcJ8}55Di{gOs_L3vl zMRA=#;v`IiRl(7-w<2-dfgfeLRiBN!4XFf(icwU0(WC_`xMaDGCu99)r-+9$cfJK( zTJCRjW{VzMUm6nhyI3A*sL!SX`!{QN1(mn9_W3mnjY9>irghzxT+BYwd1XqFN_(^Cj`XVb87bqN%3sU z8n$_?UK?n_`+J}QNi*wC6m=kpuvkDacId#}?Rl(0va)G$31seQ_qk5tU~;8|I?A05 z(JmB>asL9w`@lh5yvAuHTh!v}x8k>A6R)Qpm-xL8@#=YYErDVjYExGc(Hbl_9ukLj>?8?>T4dm`={o$z{-v=DbJ?Df?W>z7@!2(4QMsx9w4niQ%0jiI;dDoCF3 zl9mb=-B?nI@;HU+4z^R|xC;1dW%+dbU`x6-6A{GHOhs`scy z*)po(j`{pnC{MCW?75G*E=+!L)RjD-bf}4tK!sWMxAht-CJ*NgNIjCUG5j7>7#nyG z-Gr_eS}S%wdZJZSmG#^<1Klxu*9DaKwo%#sHolZSz`gUaq?Rxdk?URv8|7;#EWDHy z;5gR7=lBpC&f}UMPFWzw6TeSH90*8;1W3HdPAxag@rAnH%l2v6=Z#bE*`3g!zty~Zo>W6#Yw~sOM@w5-SILXDP_~i1@4QAak6^H%g91N2e za`r8VlO_u^xS44$We#AqCL?DlK$^}{EOecES!SpE?Xa`gDWs!Ki$DcdBiiknY?7IQ z6Fx=bl(1IfoD5llVtVv(K7Uu+cSd8gr8%ZtjKy_1YA;RUOcFM>_xoNHp3GeA;;FTV~d$q>+4A z-oZ-x-@~Lsq>}U7eJWD*CVMpmtsU3-`V4k3th5P$i^Z|GjwBV#`bM_K8hf=tnRcX9 zZk1%sTveLDdJoTh<=+;q6#bpEdu5PpwOR#(GEax?v#`FmEpZRcYJ* z&foisvbrySmDLLrddvLR#KDn4)zaq-d~G6o8t$%ObLshr|nt0^y+JV-!d-;X)N~st5$Tsw*rW zWcO|Jac?X8d<=xdfoGGoR7rwp0y4r9*>Mg=)bE^Dg@W7>XM(wn-fNN?P$pR;%#ihK z=PPO&qMaWpmwaP9U&EZZ?*rs7>RT||3#CBoHSh=ImK2Cs-@x}9ot7og(~WJv;5WMS z!?xNDLD}p96Euc_-{=@nYXzjGT?YWzfnA#+)>lpWThaz;{WAw?2bB(5X3uw@Ed8*B zPH&%|$%;(~J`GeMW_aM@2gMDyDGp?C#}f@O!RE+~N)jXjQ|9>9%L@`oXrKs6pearE zF!%>2ifl6txSFzmHj!gExD8amTr1Z2yK8?hu>X2@fBYniT^6Uw-z(jC{{R&l9GDPP zvF{L?ZZ3_>KNPw2vpruc5|Am*TS`*s|ItT!>8Gsz5104HSvlY`cIodS{(TYrJ;eXq zy#AiW|Nl<;zhR?rH`6AU&H_vrH{!Bs+s&%l+R1ZP2g+M5PL8)aOiJwHEuKD|xRZio z=sc9u11#P_;5?!8m(>D4l?8uMF);8KAMB_9GkSSy78!UNGD7fsR1UM*;xOo`2K{$r ze{4E9UZkG5-u^{D4@mAg=@ewxv2zl&`|cJbHgrd(U(ezer-Rdz_z3=3v4doq9J0mu z9yy#4>%|S^88*-kx#Y(aCP`q{lEl~UI>t829+IGn>w6EbPCIU0cx5cTJb(Gan|I;; zD}FKJ@40~}fbM_s>rnrH4Aj_|=BY_L7Ea z*;DshR$72ELEoXsTB)l1Q_%;jMLMR#^!CB-PszZ$3#GPgQdoNdVrHXuQ2-xJdk{Iw z28c|h%zpjX{6g6vzzD{Ehy6cu^8AY@#lLJ<{BKRDP;vpjSf>-oq@h21Ae=MhhO=3C zC8`s42EulJ<19Z@VwOZE=nUNLI0(Pnm_>0J{M29V)pBr5fB`^i0n*2r7F#fxGAn~q zu&8T9S&{u=#TKxS+N9#5veoyV&(nr;U7StsXW3#eGkCO=%Wav(0*wz+0Gj~Sfh2Z^ zBsCKQzwJIdb1EQZrc-S+WVQ}1$p6*18zz+L>8w}n{#q~~H_P0i*1#$4h&=yCuSyKw zDWIDcy$hVWkd+vkxd|}qB|4!y5a6sqImidv^R}kf*!*s~qe_&J06RKjzXn&Ehc2*}y?=k75Mqbi@DY&?A;NI022E zD8M-eg9HAM6bFtU$#XLMVz}Sv4rqXv@`v3&y+nWd@&B~x{qYV^WD8q)py5+6aPXa3 zmjU$4?Ef_X{e7u_@}>Sgs{e44{ykTJ-5CDgSynJ|SLgof?F1tLV|w+n)1Aau*;k;F zn6-t6aBWM8`emx}9@s1Rw8MEeKR!R;P!w?0YDxBBkh=53eFgl-%?J6*u2U?eocydL z9(;Uk#`4=kLm#HZ_fc`>&lD2BNdSx!Y66rMvj$e7rGNj!mTRiifsNA$oMUCOo+LZm z{IXuDscrS+EheQmdAMl9Eu8Q_liZ^P1{9?!`*yTe<;MpYHDaVc?(*gzivbE{U!*cI4LFpLj;k8_xMc#xOpQP8HhLEQ4ew*HRdhJeT%)+ zaBR{29d3Z1eJe-&TBTFOZi${m_Lu5{q7`0AZ{wmV9oOgG0u3GtMRp4>*00`bcS=j( z&=)3N+&AQZ{c=q9XlQ7bz6sfEYmQ_@fUN6KZUO3xK*}BRCia=m&*Ur))K;gJJsYJM zb^8AO9VAD*7H8598kfG3KGXNCY-_i=BN}nQyNe;MS`#B8xmv({tP$?-Xv5QD#No|d z(F`wIN~B5C>0VV&k$YzkzST%vy5Hm%gXr&(Mw)aBd-g;%zrcrRJPlmThW5_111GLI z|K^zl5Wg0{3Tzsv1Uf~MD+sA=;K+f1>Q$piIiq4%Wht#UK8Lvn2~LM~(a~dP{S&}- z%9*GrWHn^Hk!aaXSOV~RbB*flwhH8+IcUVbbMl--G3QaXmFY|MF=7$>ty6?2Z_$S@ zPa9pf71I;6I;A~t*Mro3VYcYC=0OtLjVn9&KvO_;&4A!eAXF~#Mm9d!-Drd*!z;f} zXmo^Z>`AgZ#ABXU(PP}b4wti60S#SDDUt;^y#J<10V$nLH1)!nC_!*t>kWK?1cgFG zFRxZM!RE}6&R~_XcKo|InuL~kupFPb&2e8n9_G;^(f@Ki#CZJ21BWN^95SN}7iA7Absl83} zP<}P-A5kn#IAkstFSM&@@MItD);RuXr zklZ)ywP*vmiT;@0i8H(T$9H@8 z32`(miy6UuZPlVGyozu9QN8hv9od?O>LFXdvZsWby>;fV&AQK=kZj*qeoo<~_11yf zHkqiBgAFPRu3D@lA#%Mz6~$>NIKv{Sb~Al0@a3l;wY4b_X+75_k9y^BlT}+$K%kb< zVp#{kc5KB56*GQlG^UKAKei|YwuiNXUXE-xV0e23}w5Yr2~F!Q});zz6!>MKT*44i3Wi+P7}r82+A7 ze12+WX8_wM*u z*l2&bQQg(?^oF(eCGGsQ*7uZlpgW6G&2t;pY~Ys0j_h6|nT2cE&Gw%mo0P6K1c@eV zRgdz9uc5iPcm*msQxuBZZa7B-oI^)ReyKCCfpLY&!g3N?TPi9&34=4Q=B?md4YZpu6Y~_x9#v^8GYfH2_IP3o4?ClUzoCB=E9i%m?Il>^}C5C=Ob> zHsgvOgaf4*v6Mc0h|Ide!>FQ(Ci^k#$Kn6R=6e#KoA?3cw*@h4sl&hN=wNu>wCaf1 zXcaaE=4rV_BdFp7x%;*}pclml?2XHE-kp4HRy5iN1pbxREekp_p?H-D>bX+4Bv-EL z6w8EsPe}kWR6?~VcW%dlMX+>){mBRB>vYwoA9U_Bn z*nkXc2ER{Pw&EXsO)D_Ew1{p#a+X`C+o81Ju3aw4EmeXjs=|xpRr_en^?}Z=BA;)~_%$lsIj$|Ew>B3{B zF_nQ(ZT-|+cbdZE)5WG?&B&=^8&JACeqde%i`%nl>y<32ffAvi*FlBVF*JJfv(Ygc zNvD?VB@P$$hMYM2YG^N1XVEL+_Z?w%H;$xrwBS zFhWx|in_IX)ZQRr!I3|4;3dcrRE}*n`0mBKdNbg$stY+X$0EQ7x>b;_x>4DyCK2WF z+I-~lvm)=Q>u=tek44O97ADNJgLs-)$v5b0NsyQw4|(yC<1Y1>ryO_dSO5)d^WmEb z4m7fzs>db@h+I|@ZP;3$t2X3EHtSDPWMjAyRRWQVQB^^`>f2!sU=il zH0fB9dzK)Ovy3pDyK%C<=6bbx>$~e?p!!c!aRXg#X@Yp&hk|DS5wr{l_Ru}+=&0g> zTNmdAk&f^le>ou;VXpYJD*`P_^G)mrMHm+_*Ro|n^nJKPp4Hg$-WF`{wvBDeN#UrC zsEPFJfj)uvzf^mlk1K%z9n^M=ITpQ0g|m~ex1YsgA351L-L2g6nmxP@DC}jaztJ@S zCJ%9mS7-s)KImtk2GOq@kD$!tQvI(ok|SnWjPA=KDI%eVwZD~I3!79)IzAaU2Q*^n zH_T~*lOXGNDVhP0Hf5SzJqhvLx4`R-U`pE%P|AhON3b2I<?jo$Gl%`OU@hqYugUam(CCwo-0Bj`>;*5K-Rl-5OSO2eYlnPrD{I z;Nlp97!6(cp}_?=f5e-SV?*d415HqNE=q&~+dfrp0MDg{iQ1_*?=4bkdD{@pj+<1C zxlrB%_6NGCf;K8n9TFx~Hk_L)Jql>?Caj2@6%Hj9k`bacLmNW1QEK0To^8_j#Kczv zc9Y-U{ny2LGgJV24jBq(B!M7gFG5vTpAE#QY1m`a#%wKKFtf5>aD9T>u7Boqg=bIZ zIH3X4jI1_mg+$dsp7^3zvG6kTL6w}NsKK1_=e)wI?kU7hk!$_sqnv#UbM%To%uA}Z z%5oZXZjynj<~L)o;V}I4yD@V5#O;ydO1+F5U!??9MQi#cdoM;vB-k4dRwM3c5HN8V zSD-qf#XSJm(Mlx&H64NirJs8s8Eq=eTeme3=FYzN-uWc|c%1mNWyjQVX^Is1 zJ}M-h_z)7u8yQtOpU{6D{ne{TYSXT!zS=#it%xb6`A1%6Ox^`&?$R8%93h*DJgSW* zfkUhKJj{&inC$8*l3gM$7u~I{J5#^}@cmEeo9M(^J%z1#nLxGRj}CIF0>q z!fP3+jZ#N7xcBE>cL}yrSp=xO0nMOiU|w|T68;9WKj4ASeofULh3n^%{djOPOfx`n z8xqi>)vq+zS$grRPKuXsjUnU3kRK+m_&NP*Y;3W)z+vjYO9c9h$>+Z;5sH(~GiwG_ zAlK67WWuy$i7ru83+2>@S^UI1Spqc_1@(H{DuT6S;%2l0cf7&mwT~JeSf$;ixCUdF z+0qkkP4Zt&^3a2lOO465H|4F~_#M%3eA4kC*NVK=_JBC@^w1h^s#AZI7sj*CW~}1D z;MY{p3Kl@HQ*V+BDLPa`qJPLv{F!f3K`rUdX-XT_PLT50XwT7Jv|O9GKco?TA@aod z9EZ={gGAu$9e;byEE0a@{pzkIDuSw1I_74&sX2jFFvnR%!KR|9WccPAW&KZx69-AO^RA;=?8MEe^-6|H8G3Ss$>_N>ktCzoZmXHfbMQ4nbPh5b%yJREm{T-H9nCm@#D&!Mf*W!bv99Mwc%9K^2V>%= z3{=AO82hHC4hsGi@b(L{?)me3Nm|Op(lsopznKP(v?ab!lX{!=sKTqzviDuTzeCZa ze!)Qsn@C=Y&RXx{c?PE#hq}{GxvW3exuyW5*g_hk7D~5QKswA5{`(B9t1B zx9)esQj9HaZoW=18m6dj4IECr$9sFpDe`#JQ}QZ>3l%krI2qZD8Lv~$DCkVrkCr;k z#2B2zv%cZ@ROW)Jm;B^0de;dd$AskXf3n7*8qo{UM6n340|Y10j9~=gkR6~)Y8^?S zuh>zhAi}=_R%vswd(BifzuR(BQU2}GB=$(D#%2V<13A98%R$O+Ti4OcCMb<0`y8as zQVtG@Rmv#tj-oAJ?7=jSo8NXda6ZY;aqkD6$Na(PU#8(NgiC#m&=j%Hpb8+3(ND?% zM2rdWW5_up2-Elq;_w%lM@kt6DLy_3PbPKeBo%c0ooopolpN}1PjluNeJ5mGf}o#3 zwIP{M<+M_dr;%g~KZe+JE0)=ePr=GQ9S(#YDS9?3cQ?6V_+EIEsVe;{@=rD^>%qp> zt`Uul-N$4w=?GxDJ_UCo=@0}G;&Y7&u8+FSD|=b=)29`O91=CK{xSRw5!dP17IbeK zD&hAq6)x)nZ^&RHj?rbZMP2b=(J-hF? z8@=-^tt$G3T$ z>Q357EwCELt=h^C=M8O0Erertd%hg}f9<_@R8#x9_lts{RHb*6B1%AeXA2)#&^5^6$6N`e|9B=OF*_j~R;_S)y1z0N)N-0|Kq z)*l&+AxW5XI_K~Al<)KTzFQ52HVHC`WWh!ggdBu~UyBjk@N9(UR@-;0xBP+_hYhfw zQ!qg)v!?aQ7Sat`v-!!_PzSQKRF|R^2csR91moL$z_~ep*xdfefBm^GWuEf}#0#LE zrBN(81d~9_7_Y^)$BPwOf?F3pEyK6B_p7z8W4XoPmR=QvUFbPys!gw1Shhh>KQ<99 z&<~0vE8w(y%3=)}QMS-Aiz$YKcP>7vmX208;F@RWzgB~Phi$SHL$M6z)G zcAhe|PT|1M;G+a>ORO$X?H8jPFCVc9%9n z%r2!%vfNNoGh4R3jH`;Hi4(Z-64fG-^R>i5xBhXWDqA0QeJ`9++l)f*P^_1J159m!Vh4zerZ6%*i^Mbmc?D&22ske%ZLz&--q@rqReJR)UC-Vow&pm)W)@k+|GvIG4$ zuP$$h3uO_0V!=oRraN6tKvm6)?;B zmKbM$S(F$vPKkCjNav*_nY;oRjGkD-cFXm?xnbirH z;5w1$xCuZj!AyYYB|Guo`I{1-!vFUD@oMlqq6y)8@s6!ZBIW@Cqq6`WuWzX*SuW_Z zPa?})O=o17A#z_`!UP}K&<;^=@Pu%&;cc#lqW|+o>bUIR4Hf_Fe8hi2(PpRum?i^0 ztV~1`bRs1IVG=WJhRa%S{g!uk4pxCvh?(?5?T7LknD1tZd8~xGulY`usK30B>M5SpY|wS zdFv3L6UIEmJ2*w~WDW=H49;JJAPK>#n&GrV+Qd&at)McqJ(j81?7)4gZ%9SONtdSd z7*-oPH~eFUt6LH!eoIJ^etKLhI_+))npw7|7u8vj14lxF)dM2!vrXRcr$Re;fwh~6=7?bXBxTUxAb1Eg?a*G1T} zcfH9nPj;6@%}{PwaG~U#eez8Z|FiwF@WD+EkPYk{jVIWWtJS5~ckTZQ+Hp;Fe;k)HEat9*zknC7{JChW_@-m5lD zJw{N=Z$>jSBuHC-o8ywqd~d^O>BXuokJmC%;(Lct>T0BNG956l0`B)*VCi|;QL~x} zVub4J%@$xeqV4L*gSdOg0#40s9o1k7*EGvlDV;J2o0ltU&oW|{ZfTCdwd##DpFR9< zY8cO~Th0>Ga~R-rlz`@PGG3wGuPqjsSV#uOz)mUL;3q~!vz1dpR84lanpl1Ey@i!i zCPLURiU;W?zjHsS5bFl*0Qw3T9|V2h@zuV)3&`XNNL-!OELj1#Lkt?2=Ibyty|)6< zO|OU|tG5(;TD5XMxVq)*moG0b+aP_^ruL=POg~cTuScAxV}IV61kMp)K{!h%T*xCn zBvnfSbe+(CjCM${qULHm2YOF&hdo|BA)~i4hb^wvNbB21drj&=#}v6bnP2pt@#7C1 zpi)cmpX0dxeHWal4k?R#t%@kxq_BJqurQ$m)6M1E?zP40rSx!nlVap05rb~mt=1{| z^;3=?xQ&ukp;h=$U@;3gH46S>Y1muExr55-8jBg<3Fe-tXgI?k%l5`=yLOl!KNM2Q zY!@ISqc5Zt#=xELA>n;)Y^O^KQkbFdyl$E-0eDzCE)5LqXU|t!Sph{-X$EN3J*;R{ zLm3Z)XHOCOMZ7u&E!2WgNcve93w;}zK9snX@}>U%KBs+GlnM_pw*xKx`5%Lgv2aicueDGsZousQoqI4RHhEwqCo`Bsbi z^=X6)-5A}9w#ea$JL<8zAmY`$3j6YSVQEkJ`OY|LcO!ra9n`^3ypQGRji&~)5S6|> znUNz%dwky!ZGsFmnX=q!@42@Mn=s(XXB;Uo^8pV4|1s^J4+%opeqGWBz?snscOK`C zs8{%iMy~4oaL&|itNGGqcB^5j82_|b=2m^8U!D3+Qir1#|3yE3VNzb3$;ahon8Qr4 zira}|&u|Wk8QCSdDmQE2RNpwBi(@r)acH%rRLm?cX-@V%t9$pR^alGQ(%UzQyWKJ5 zmoE(Y+<;mn$G+mJ6?q((P`$DUg?Dwx<3wM5AEms52wfIeHTLmjJv;TndBw%$nK>pc zfY{7R>@cVQg2R70y#uhm8DQ6Ob*t_D@kH=ytTY_~iB@WCpMe>8R=KIjBVy!*s0)gX zrG2=f`WbP&8($P}INp4H4G-ukj1iZ}R{;w!rf^~0SkI^_1BXrwW@e(Y(#rj5;LciO zi0qh*ftXhQryFcbW=Bq^*1NWX<3zU8d%=V1EQB14G(YsN_O$w?uk74?WgoBB!E<*r z#-ei*Hs_@_v>D!n(!I@lqtcslvg1Z`v@_XXx8pfsF&~n2k@^W+Ux5JW?_K{Y!3p?!8zG(C z$t_BLplB}fzy}Z=cVG$Gwn)F6zIe^Os`A1W zE0@a(lYS`?T~(uCg7A-`EI?u3b*t^V9lfn)0Y|WKynTq?Uc7JYDjO9nj*(Sbs3FKH z7vBAfJc3Op3avalA|8{GN3b!)QPi@h;qr^ItWB>R#J8tS4>elw{Sm&y?M`E-kMe#7 zdR1SVRWCR()QQ%$sW)Q%Yb_1^T3i*voLyBem zo;SQf4bG$81p)ZmtJ2Yc{^x?5g2L32dM>;$%gX&m_kk&A$Am}h^(W2AhVraVHygD; zvT`6)9sV5wd8$SpuswrC#IPU%;?9S9r3OiOua~)%wV@M3S}ZC51wO4dx1ME8Ii6!A zdM%!7Anx_eQ^_?jBfQ&gbqU<9?hl}H8r&--h)bV{h+ABWkb%##?;V_G5X!#N1X0hZ z7gh7fRS?oMoUCTU(!Wx-)bPqy04IksZ)s>%IPq~wH(E013Agw3r)*r;Pfb=pncl6B z5d6}>qYg4$;KA1cxfs0b76^Uw6?B_;A5J465HGW^51NYxRzZSJ#{^yy@$@txj+Cwr zPRdyhQ2yzXEl#QixiN)j6vu&_40#A02YBg7+glUgAwHO^IUh6wO7EaYeeR||YHUt_ z(Abo`FlL2gdsAE3lqQq}9(v@@l%GPr5P~Toa(2iVM#lv!F!3w)fC=|MC+9p>$+v_* z%LMO@fk41{&#!EE7^2!1nPf*-MuWho!okBYff^GY<_WNBg0C5JLxJViw7zvE$~Veg zE7NuCT)nAZBYq~&V#E}W#|mB!DDZ=fjD4fv@nUZIIg9;Drj4v}K3=Ar0lBu{A@Vrp zK~)Vi`)1NIBu6*CjK#`l$|Llp>#TZxe4JbTa#+)6hnp_ay`>y%u<}1JO)1@JJxGUC zY)=)AX07Y0v1s`VCk;@FU+24f_Pl!PPoHw&wpC~Y`1VY4I&G3TYE@7a`!QK?S{}i? zc6o%Lsi5}m{hrCCl%tArz4>%6 zo=7fAAL-5GE_f&zNZ3Ok5K31to;?eJU^b|1uW93q%E2dl_Z1iH(r1iDiAYxcrXR&? z*7fUR=S_m_S-+f+9TX0NaTd4M(;g0%XuV#Pxt^x9I8eF{>%2*8PT47<^>Xz^nThET ze(X_gq|wxd?*73ghZvm!#}{6yPqe8ndY>;dNpc!RG&m7c7^KPl0@U!`JH@k;Cf_{w zEq+l5BY`P|n*Oewlh-akzNebq@%>lBMz25r-OB3EP7(jRsoDQ?wEIZ#7`RRwc{tyX zF3QCYBbk@nF1o2SR#fb!XVk>Fm7OlRZt9o46TR8b3Q2pN7s7c~-eikQ=|pBJWQz2<%X*x4STq}QbGAw7KWOPYT~;r2+5*t@Q;Wd2}089t~8qDK#7sKb#Ii7JQnwlq(YHgGT_x zQDmrl`HK|*ScY9r@+@*S`l{e%;bK}X(ox8U02n;-I-UBj8u>Mbn!T6~x)yq!{~3?{ zM`Z29H@ctfzAGVMsy3s1XgV@m1nU=F;zE{9b;6x%_?$yky<3|ntaltWV2Vyt%D+7s zamDC1T1yhju{s8nio?GZjv)e&~=kb9_4_E&|}JnNLW7UEW&3XP``jydz076c^Z^sXzg$HNqT z*A_14t@J$F@f$1ct?|2VmCyB-?U9L&d$=$oLxA@Fg;Q%oth5D=Kh_hy0hE1S+>$mo zbsMXTPAD$PJadUOl6lsCWaXRF!9JfGg20DcGa(dWRybe)#xa&Lz7ncpb?=jvD!K%v zlU`Gw^mg+oSM@gyK5lvOe(NvZL$e$*?U7$WHHUlY80o0v98TC>ETY?=EHTZ!bl{tr z#XV{DGyBV08hgO9kdU0WCQCm1P`&e=At}|bhoN9^XewyzM)$G&zSXR?J)XmXK! z#Y9~g5S2dG8kcLa(Q}hY=JsgRxYLI9%OEzzYdA0$c{Hc4st3+KymlBBd=|UeUO85@ z=sfAFl8_GZeR1N8lJh~;*Y2>yb{J|@=Cqn0kBJR}Vdi@?hY8H@j2Gtnu`Jf?zwg4W2%nDUUKEmBM zMwTyGZKrvSmT124QL$F(p)b2GJW%y|eIrDE8%{%}gk1!jO_c%hH6;|JiM36U8}$;& zjN}w#yY@+4~8I%8R!fF%ptt0aE3VD#sNl2vWlV*V3#Aat<7EGIy`CMnU z>LVYM+PobWjsGMsGP1*Ds!=&q-fIKH&w%Uh9S-$sL59n zq~LTeOaQ4XFt*}ZZ@HZUD()EiZM`-2*q)V7`!OE7I~vR)nEgVMZ$ z1D()$&rWrUX22!HGh&%zf+*=9z?iR|=vZKR$4+viEn333z4e}ui+%F7CEkw?4v)@@ z-TcblaUScK7$>cM#lnUC;n$P+a&|Mz46DATlm#o0PLwGfQ$t9NEHv(C`TZ&~DI^7yE%alKh8c+oH1Y*7(2kF2qHsIM9TVCCqlV zwrA&f1v+{<`tbcoS=JhK{ie%hD1})pd*;uO+!^{pnC+b|SCXh4y!Q0~xUMRk<5MQRGd4kj3PZMoG`YEIMu8HTu zE!ka~3a^ZREV=$M60`(r>!EE=)a+>D)qKk=b~)Hh{n<@F+B@LAN^R6+bigCc%@Xq= zXID!o)p&7=Gw2Qb>FvCj%>VOcoeo=^kR%b~Gir|yPukznhpCc}+^FZ%n zf|ID@*Un!}l60~vbE)unR@>5)W%62=p|?KCfMw5LW1=-VZYbFFa(&O|-QT-6T!!dK z(m6GNQWKsN1^Q{PO_a$&GM&&u`+-ql&_(!BUv?JKc)PE$DPVGE%~--N)jFi*uKi{H z54`jztB?H~O)XR3w+83aT3daNP!>$On_otMamf3;P>K9E#6NvkBEb<9A@H3Qmq=z0 zz6?w=$8-BL82-KO^oGm{A2;p;M*e;;K&Q#Uk=Kbgeo=fV2AWQFI2vHU*?FqjRp6h~ zl7pnvn=r9S-#`ObU3rq8KG#}Hgrrr^%f@2&I*qQi*9%L_26S>Bl=(8uag#wO0#C%O{SqzTuUI zp*SqPk)z80Osy&t)iK)=UEG+=w!8b-Y0+%sM-!1HQZsQCU7w7GqZI)asAj!n-Ug6x zCFDUezIf^d*xJ3(ST=muL;_82~*J^W-C2UJ|7)$|2IIeJi!+{QT5PXXm8 z$50VS@vY*|uuH_PjnlU8n=QX6xPTSG2c1L9#IoI*n$SGi>*;&0p(xk2>Q+VXh~F{{ zBJq(c-uAYl2d&ixjTZ&c5d)vM$EV^1`XxE~j!_-yzIo34SL$XYA1>>9oU5omD=oA) z_^fk;v%`ZQ-IPn|x<(mYO$rN^*~wz5vE-J6EFeOOqYe|HamJ=M>P*SBm7VDAos-ZoQDb=Cc z?2w!Su&SdkZ&@Nurl+*Cb<{;%gKuUHJoBHbI@h1heqU{*NN3Rah@nlnb4;X&JOt(o z=HFESxR{4~bc6S7#irH)Vr%yDc}d@e311J~+x^9~C@JAY*Enps_6UbWV8USyejhOX z4M~$lp_U0#8WBLRL*F4tYsu1~g(uH}`hIm%fQAgGx2%m}82K`R4#QS{ynJTnJIR~J z;=ZhI@nXMs%@DQT&G@(CPqt_>hy$Q%(VhS@BecIWy-9_)wWuAPNV}aTTQ@XFe^$94p@_PQ3@){vxsn!P zchu-><$gV0dkE*%lYBOW8;I70U)_)j&?O^JX2Wwog&DV0Py6aTO+Xz;UeRBYDb@RS z8Q{W0Bh05>df)6+vq{`v!}c-Ie(mW{nvh4(1C@ZM@b0@s9r^SioNV=SQkaKehT(GE zAm=3=Bb=b3h7N`W?@Rj7247oY10o4tK`d$A_UcqsJ&)C=TUr|h6ZK`y?-VRi?a4y- z_wE{qj{xq0uJOgAM1xay^0)vO>{2m76|-EJ>r&jc%%h?ZBK7v$C_c7JvOLzyXHzTN z+7Tjnmzze}>B(~nd1qf1@9m%oY|2_k4o=%qLEjC`&)I7}?0_8-? zLFkkFwihg{7~c4bb@Do86E;qbVKM~i)qS{4;=}40UpQj{^OEz-@q{EsTMl>IVoGAW z)R8L9+V9XJhdP)WW-Gw<C$&nX-^JBu2|jNgm+@D4zOO01gK_KCpk%x#_|ZRhibF3{9DYb! zRs_t&MPBPRs$t7gzA4ix%VX7ZPHD)K>emu`jfuKA#_aTrt*{O3iS?ZT;e`Y8EZb01 zTBG0Kxq?hCZed0v^EJN*>S?p&3ov(_XcU>BsPD-HP;kGru>=ARwH1e=>}KrgX`zcM zqj<>yT!+QeBMZOZ6u0s>;{QfsuSvlic1QWfYa{ERIl2aSwL|qYPmKf5XUv?Bu+>co z-k#8w7@?s2SZ+f45KJkTHX$AV{p@UALq#)pYKLQ%UPL_2yKhPoA4&$fc)i8HH3xSg zSk4{C>`7$|kv#Kp+IX!ppK|L6EgU_^r9_nxOIGQ3j}0!r38i>a_#4}9wjAk=x{&z_ z6e#?y#y2LRN3HHm?!8#3c*-*>Nanx&fJ!$vwSOC5)AR>Hqs+em!AnQp%i zibb%cbMBfPD<(Z$`&CN09k`! zAIdXKK3+o!n1#|wu}Lusu#4%Q>~cuBwvp{3e7j67nJU&9GWvei$7VCB5SrM_e+e(iJ|2MH z93-R{I3IiHmD}=7^4&K@uQ#RdeH)0-7^%@KyE?-qUaIAiuT-d!XZ1GS_PuzRY$Mxp7i&k zW*WTcmdB*r8_Lerd#+?Yma)Fql|wCTp<2uAmEwQOO7tBk@_2rL0(^b|sQ-`A$?|{NNlE5VS8uXE2go;xyn0498S>;)- zJp^{N@*qi*b}_HnG-;@crzTt0)<9q%g7pxHR$M+m^J7WWa0)#oN75TJZJvIj?}iTk z_CZJgVnx#+jo4_`61DPL@U`HvLC;53YHG)8KX^QIe-H>Y*qSzvU~cK?7x|bwvwEivAdk~*r;~WH)8fyL!=IkBq&!=x7iLrvJS0$G*@7!Z1_KrU zrXuU@Y`)n&d2{^IAiE?4(sT8aYa`U9YvtYY`k@B(mp)1e0tiPFY#9h=R;9ziOww|0 z`W1Xq={@?8>vbGQ_Y3ar_~VreyIJ0`_7s_j=+i3O|II!p#5IRKnBCd4u(tx5u2%saf?KX5GOcog*GwS~@H19b@z#RdPG*ILhpU5ZAKMn%<5-IoHgxrl8!N(!*_s{vH zt@=FN&H+qP2pM*s=rNA%j8_r6suvqkub5MOuleabuY^Op6~%I(;ZJF(J2VIer+g~} z*}e>>7~dsv?c`xC>~dMLcJZjcRNm8R=>{gib3?9ig0Dyhy(lPC_qx<9#b;Hz6O;g^ z^_bG{s2|_JPIITm?wr_c<|>q3O@UDPUyz+&(siQ$REsOWq}wd$$^Y~~88CqWObV-D zb~qqrMULvNXaPO`7`b@Hqy4*G)VYBS^~oPqy<>$w+GWd}*^1dA>SGcaptARJdX{fY zLtbPlOkdA9IC2O*kGx^js(r;w;x?CBGR;fk4CxcFlB^^EjnS3Z)$~r4ghc9SQbOZ1 z@mYnVLeytR8QFd}wd5XS+M2_MRo@s-+W~k~ZFVMV3a_3oi+6_k~20AX< zGvBUr3dRLAyrlHrnDY7VX8nanYy42Y8RCRcc&)1fd?cXg=Eo;V5n^VP;g(yCIZ@|624zCy4PAr+87yT)jYQ9=U(U(7A`^6^l?Qf=W4n#8X7P) z0V4_0C~3e1dM2^Z`m0J1xvA7`_G!QVWPQo2*>vMeDGhYeL-{EC*d2T>;3|CzbHHtUm@5!L|s-GzZ*zf z)Hlp-w1?fB@stDx^o&ys$FeU6Z8TGgw`jfOtN1Or8)p~`6JHHt_GE$18rM&JUkJ*x z`m~e0Otq|0xg#u=FZ`QKfGFEfZM5fHX1^^pVU4MO-&kY3zFih*#GqOm8q?7WSsDkB z2YBdM8Wjgu4C8O%A$O#Y&~H8(){}*t!Tjoy!Jk{@g83CX_;HTkUqUvE-Gn$(wFgB; z>y72is4u9L>Tl>6MH*tL@_EW=rA+;AJ^H%V)J4ZfJ=UwZEHjRt{K1yGFD+oyWG-sX zDO{vXx9`Ps!%XbK}}v|m&PHs3o0mo=RZVVDw7YUxpu9L;k>L5lLKWj$}wm83lkua+_MlMTt3n^rSH z$BSD}5pR~dnl_@+DmFK~>u{puQDX?oA}-6(e)3gdWtc1<+`TA9-qd=Y0_g@boxOH9^RF)g`d zXzZRnIer+vV%qQxL&t#+{LMtMiRD1(dgo@|(8f~s7(nEU1I%?Uzy~q|0n;a-B?jM_ z+y(S{kNP{|EW{hLe(D!+)bFUXyaN4SCV^eN7e^8UWfyhmla@QnI~?Mhj-P~g3MXYa zr?-#slRm&5bb{5~g0Fn3l%FW>$1t$yPh_yypWfD-@?{CO-h8|$JeJ->>A5_3+VK52 z40dJ}6lrPij9{wQXP_Nj92j?*nLzbeW6jH5KV++{$q)SNw&E8BR73B~pYn{&3`qUU zhW6hKum7=c9Q$9i^8G`VRr?>mtpUaZ01bEeuS~arF(kbeqv-~oKr0Q1q~#=4=tR+r zGyE=dH7<*F99^6g^xkx)Gm#=VpS8vuY?IAI8(;DE%be&RBwwj#jZ^gnQA3h@-Stzd z2Es;pQX3}2j!U5>qDs5!0x%masHZAC4a}u>%X>I?8705$0xy8UEF8-U& zxd#`%+G^wS(Z#*<>S6>qfD1a@%Z#@&015(b!;;S|>_XkF`eGixNM=n+#iWS{vmtYZ z#BPsCW2NzW?F8f16?zv`Rjhnq>=OG0gD>$F^Re13%`ItG(f(F%hOZ<)vwqK9+CqUd zah{VpFq#0CVNiGzx8r97W{JlVJM;d9GEBQ@arfc9vX49CsgLj&W$Qzc>2lASnAWDd zy|_~dLCA2b0ZOz(SHSPizUZGymZUv6{~$MzRKBTdSSNOWqQ&o=ITveRXW5e&>=-bj zL>6ztX&y%r4f34RUOGlbR@FmDIWV5i{6m)8Q%`DhU2aj$!{m^l)n3^i$g1Ct0tR z9$DP>d=r)`?DyFX@BnZ4BJpg>Gabfpss53a&QNm~7pKr={APy|DF*)W{3i&*4RVE^S@rK0t%a;Z&AD6*7)Nc|fSK+S`<2tS^^SJq^N>*T^x!q#R zq8~7G3f{KW<^68LcSe-Km0lab5BNvw{$lme3_jjLa=J4r%sFjR z_lCw<@2zC7kl)k+C{pNq*ezUD)B#ZlvwzLHDACce!ey3YX6DGcGSjQ%F1NPYL}%@N zJ72TtB_aEZ$`mywik!XmmG=uK-A{_q+WYxfBqk>wqRwyaVtE+e5Tq-d@*oUcqmTo+ z80v7bI)Js7LjSth+j;QzMrg2BMws>eoanU`{LW4wvFft!Vj;%%4$J zNB0rpkfn%zEh=Bu2ekO8Tv4|HaAHnFA`(77Yc}-)&W+mTfCSRnjETI`6|=Aup0LV{ zKGu1qy*U!2K;zNoWt)PX!T_19_zE;;rTevYrYFO$w+r*KUTL+pb?2G4x9_q$Mkn+= zGdUMR*GxbAmOQaSDF;STq9=DPgQM+yF`24PL9`I3(Fj%LgR@zar9x@vHCm$Ae4RAu zX^g%J072566Gos5juO?trANpUGP_Wc1|;zh%ErW!lIN) zaw0qd@h#v1lB$c){everWV~N8S>nJ6hX`yST7mB~c^%t-e;+ z-QL0>UayB&t>V-9-%{rIIWT5>R;S7^8(eVy+E^4fZ&Pby>FZvv=S{N@Z^p15^|%VA zp6we%emG-(bVqGg`qVObR9%X&UjUWWAq15bg)@c!cs$K5RAVph$#q0a-ITMH@G#^~ zj~&;s`0L+<^L_mkma-Bxu%La_RZuj7MqVHu#OVHmA-MlRb4!DQr1=xu#0X6mzKjV3%`swD=6yQV5{^wKX{cb0x`j(>kq z(LU^bSm)tzFyKj8ckl_zfwylY$g}5VB$TJgdM0blyQimLNPi5?k1;;~Cb_b6xPI#v zg&|P#Ijg3LZNgg^hN1lN{t-l7sVraCrVOPdbOPDe(dzXiMwc&G>shd_HRW&DTvg`u zGxguD)HUr_VQ29vIO`4;Y(jeJ&QargRC__wM2}EQt?p=D*Q zM(M8se!@ybzAwQNyZGXV3jEf7c)*tOpiNfR@YV6) zSLuiqCa1{*1ez9Gri*ER^dnzzGH~uf!skUDGnXU*DcsiE#q2K+Zf;K5UDr>y8EcfI zYd3p1US9QM;f`I9+ND7+*V=&Y3l?{v$lr4Djaqy3Yf5aJU~YBE;%*z+du}#ryRGR_ zKguMTyQg*6%M4!h)U|~OxN0)%3h@=Idi8k=5&E&7WDbVZ_;jL3upqW+&Sqr<`{Q`d z7P3mO=cm4UGnMyAimlbDCPBKV@en)JN9Js3omuG$7OGD^y1^Y7S<@1uuUs@&dOulv zv%DbWb#A1sU| z=Xh&gLR*{?l7Z)gV`jS%w8O0G*Ki6cMQ!6EBW}Kd^dhTCjlwZ}eMXrZro1ejn;q=f z!@USK%GDf7LmaE~kvT!-uvaBAYCTG)Zxd-2fm8T+G4gfPW}FU>=Xs5^?ya>^y4AzP zErQ4g*xeRGf=<;T%nd!tfvotrFi3BJUgAdQ*1D`6jnrtW%IZr!-mtKuiJ3~4er70Z zmH)%1FQr0pvZw?gwh@uD_b(yI5R zd}WzjO&8yr*>MrT?XXNMRN?tXmW{<@`f5OwX)4|285@i9)Sp3pHB>PzM31^2-$OLW z1PrBER*MZ@xwo9$gBvJz?%VT;o9#jM?Jl81{lZ3+6%IG5sXFdJ3SO%xk=_DC7%PY&MxY1IYHm=7h*dN4@o|Ev)ISP}m{i)o zlC<`OR<1)|cVN)ecsV5w@jqt%{`#mPA|uXiw0q z8jPUBFf->5wEWKi-xjr}zbFuqz_eBV$QRI79QYW>UvX@~F;5VJ&(hw8;;XgJ!0SAlW`;32|ANcYo%}V}98QH)@{k$Pr zHv(9!?Gpjj&5z5|;yYqLoAAcKsF+sz(zlSL%*qA?nmF zhaU;8hY!+b^&^xqO}^Rd0UAcapOZemx|zOdm-UuQm{u2jr*6}8-i%Dkf|f=luEAr~ z8FyZ?wmyC-=VR-PiZ$HQE}yenx>b;VvnrLpmsxC;Iz`#;_2aE5!am?*aho8!3dl}* z2%1pCQe&H~Kpn?zm0 z6`Wx=Dv!_&V){7wqy5U$`fBpvR0H3UP59f9BHYuAfC8>z4%)|0aGPXW5^(13zbL2) zpe}gbD+FW3!3#JI4Dc#@oGlhGWR$U%Bb1Yrbd2_W<88Fis;%yfV5C?8U5*}W#3Z8Ki2;YE0cLB#Dv`k2#5 z3{#&curbn**+y}Zn2rw_3Xx9q%uCj_YI&ersjTPXZ5E_!Q6OKg#nHMprd6F4nQJ}b=9;$|a`-T)34R+oPeHCG&soy!iw2%b z*f_)M7+Ly^Dw0dfx>GolraoU(>mRbv2sL?&J+ts_zr-sc`sT-559&H|8WZ>0apGv( zI$T{h|Bd?0ZZf|Qe_^1CJ^<8+qe*y?aKCZ&;yKkhv^TUWM_mx!WeT@nIY+$SKxjde zyur-o%ezi`F+Ab{Pv4JnYQKHctP^FPeD9ek*W%gr4B~Pk{tT%C=7R;Tbwrl#aEB+9 zt?}Kx^F_|NVc&8H|LqZXz`LRZOyJX+@&c9DHb(mUfOPTe*D4eoUA3=&YEJGK|4`gL z*T#l{Gk!hs{gL*YyuN;Tdt;qJxqX^U(miTCZRMQ>0lvq^>!E>U!Ohgf5*W{^E7T0b zu}@bFrR$n)wHXVOmp-S98ECNJhf4WrznIzU6^Xy}^kIDRhWSO^)hGCz3%@8l#^z<$ z5k#M0^~$E-#(It21+xN0lJ_9z-}&Tg%QZM@ zYiu<(s3}IB$(5h=wLyv1l4M$yug^^#zTBq=gomOifA~}lV`y-<2waLaNVAUCWf?8@{zOnpf+z| z5m+Et;e#s#9&*ni+b@b8kMQ3o&pNLCqDVnt6-m*{;=nNK5^a%ce2y-F_z?Op**g7h z?euT2f5cI{75`x?f6I4^)kufw*Pn(W0;GZeG2c}2O~kzJI8o+Hl8!|7P26j{MV6{v zDktn^5<}2++bfu{`EcH;eaxn!~-~t`&k{E#T=4$VIt>2L!(B!T5l+MO>OJYxsZfp#S>4T7brN z=WnzWd&7B3a0;>tQ>+}J)YJ?o=HE8<{K^4%On}UhY{`a2W2l!l)m~&|0t1-jB zDB^yPC0tG~!zZp|{mJLc5ronIEpCkmIWV1ws51iNk8J6H3NxR~IfcIsFj$ON4~ds7 z;J6IA18(4k00UHoKc0y8KcDR1Vu`9uwFh^D=lIXl4I0uwi~UqR+Q)G@l~ak<0(xM= zA5O$=f-C@N)>X0ZD#2**tM8ul4ckV~UzDAfh|862f+t6R;!^tTl_7WMtH;QNsHCZ1~{`wCfEmb1ZM3XXt zs%b}zG^1+C0Z$M3_yCZ0CYP3r1I;sN zKT&ejll;o_5`5*8Az2UbP1*$hriNk^;&7=LP)i#Pb#K*8*aBhRA3hK0zr$N9fWwQ& zNS_|N{Gu3q>|Ncm_uVWG-n}>jpmVfv9HdiVqi2s1Ae3ojF+4FUzPh?VJY z?Qe&HD<)=^eXRT0*f|bxfWVL!jQ6PuK` zz?rARr+|FuZJZ<;G15 zODk&|Tjx72cU|4w@A*9P_47vtJPv&p79J596`hdyDk(W7^>tcSc1~_y{`(If%gQS% ztEy{i>sngd+B-TwcYPTc92y=O9UGsR#}gJ7mzKZ(SRrk0{n{q)0K0p?=>qxrFJyu1 zf1&Ij=;8(GV&1opWgpvbx|o>#e-qBTkM-#3{d^b9*_^!jrOrHM7q}RoS=!7Yt#X|x zc>7`h0U;UHd0EnL(*8!-KSx-|e~PkyC+xq|H3`uJh3t1@2Hz~q%;2qJ0o%U)`+m3m zZ2SM#*#5P#|E+QSZk+$#7+@z%zmH^LVFllu?EBgOecwO5!I%ccQiU-A;bLI|g^7h1 z0)x=MD<1P$Hz1f)u>{o_tXa?9zWB*Gj%;#|0l5ojKn7uy?+i$o6M&!_tXt6=*I{pl zX9ro{(0gzUNFI8pp8+`lD_3Sfeqd<7&@FYE$N%j6!Q+$-4HUVk$|C+t z)lCDBNL#nv^X$HnS}vAy%eY+|`84+}Yo^7k^Jkdg0-C8w6QxAU)8#>;37yTJ=DrwC zAZ^HD%;94h;^LK(I}b!9By1!^m4Y)vr(K(Gt8{}uS^afLk6;+Xz++b4#=zb-On{vO^Fb^R!Aa>jj zJ&VQHUbeV|uC?7Y$#Pj?ak2?JUR{z7L%S7Di|qy7xLi3@T$EFmj2B2+U+R3#uNh)q zm7sCr>{*#R4?M2qIOz+RG3g6#MTEdSU{9gEXtzGG;4hMgMr>C*;XFl!#oLoSdFCho=CGIoTmLVsE@;{Ex-^NO{A2`$&INYn{Ude7JLhH(nPgj= z79YPkQiT7itoWcHHC>d|KXad_pH>JBp$Ex|KK@^IVR=H51BKCw7C6m-oV`ag`}?n_ zV2u8MLV(en8ZdU)JzOlb3Q83)ZGo0!+jThSi{pK~1*@YH?J8ba46Wry(@?K!gJ$nY z!r#P6eYk&_z1hrzl85bLKw=mWq8<*A#dYFh9*=gK#-KT^tVyPk2ywF^gt*P{ZJVFs zqRw1aQS5AoKfZ(Ct1*(FdM%IXgSTQQpk#H@29*~e{E@t=eunqMdquv^O1W@-kVv#MFk27Ix#+A6j`&iHvR=lTzp$DHJYL03be( z8*jx6w|2A4F(7P4OW!SR1H1Fp-yS`8H^j~=`leDq;u39su`B?qO2krmv2>22Ib6hy z3Sc$g7p_kH4n34Pc#FiHy`uT7;IV3g?Qo3Fpz1^EgeB`QM$!pCdpgyE`)y*9Fg>Hq z3rG>hL@i-+#p5}^24;*Bp8q=)z#TU#)a-Xx5`crDJ-0+iMDZ^cQjQ< zlG2})p2P37!vukBa!5aJ4g)P2?NC0vLgxi6NNk_TdvTE)3LCxYEB+o{mmc(Lc};H_ z#J@+yj*6GoyF&+Nn{j|NmdcNr(`dnoQAGg{;)=WpCtfyxO#5OPe5ThY!0q5An0r7E z$$&@ecKo@8g)N8Kb_N8Hon1RhTAmXI*?bosjpHe*gtGyBA(p2(sfK3W^IdDPqqcL+==kHX&OEAoqOWfZxUB%+b8g6 z)R$tuzD%BYHh(j*!g~Oh!UM={G{Ye1=BqeQ!~_okyPioBZ#zLy4xc%PF(J}JU5j)=5vQ}luUfg={|+?-%p*zCIqXZo5gW+>F5f!PH&1a${cX<^d}svjou8L^qB0H zsjYb$DwBA@Q`_t_<%vR17)In_YjkRtd~8wNqBCCO2~~^o5Fn6Av^?BBOk~|i5&`qX zsxBv(Y0$IMpe*i+gBtewkRh*}lxuY~&-A+N^cZzh{@^km)`oiluTl<$&7}!pL{V0F z6P_DDm~v#rTOYFlHPQQO;@#F>Yik3387hgg?PcMv=j3{whtlY2XgBa~NSjjmJ;-GM zsP`r5nkdz(VeK0}i|O?>$_NEZV#}#;yp|3Ag(U>y@T&ayfwm{CK|BQ0F;lV$2^^!k z!pPCKVD2j6S=J~9~2OA5tgBp$H*HuNe3|`=4JbY_KaDpn&`HRzV7Rhb{0+|$5cg+JRH|CK?mCU zuW3<~++iZYM^UIjs`4UGjW2$aW*UuXn)C~vy&JE<3_IR)JAyZ>`1^Hr!nv;|0qwI? zeonG@BQ3rN=Om70`3c-`eS~oO#(-2*GFAC#IS5fM*HX-BTjg^-hG#pb4hUN8vK^&v z2aip#J;8Y(00nppVw{Kkl@zuUK^Jt#aII}m%UyFY`(e4W*BZtCvb)wa&F0_;7gT-j zgy?;`XPh`tZNh+r9HS3gWk5-H3qHmw6Z9K%!wZzM6^DD0W7Ixo2jvI2@|~EnK78(W z;OMVm288tr?NyT^%6Yg!j;9qij{5{VTw%)dqrlUh0pXDRxOewM{#1(ez0d8IcIRWn zRqvYhG}mZbont`ub%UqU0dG1hYz~ugnwEs~;#R&)lEDb7O~wYcX{x98Nn+ffT|#7{ zk#NF_(HC@^p|q367+|vRwYf71=99R=M2|wP)-H+>K-H^S{aZ~Nx>N7ew6?F z>6MA?H=`QD{WH_EM_%}O`znmt@Lo(Ey^s8!eJr=v_A{z@$CWre->CN~_#m)KIYl3b zm&SoTKv7!X8iGhCTQ7kkj%#Z=5px~WE(G^74t%eqFyNXDdo5%2W%nw_;)_9eCbSf` zc8;RG0$MLPPaIu@WLZ$e5q#M3yRP)NeQ7;i+B?rC9ZtPTp7uEu|0)2Hbl@UE1Um&| z0a?n4n@h$VY;ej0wp!4fBeOUAebYSyufAH@OXrlIJjYckVm7^Yxh=v+ue$r8@Z%DF zmMQvibh9$f3HlsU@im@u8>I&Xc?6K4m+H%L)g!lS>#F?f27B&K*kp&e;or`0zC4-) zT?E}Q=Jbzs%rUS;PTYhY0X#EyjExMCaIHLt?pfM4z(wE&G3L?pRGMzbCM`4ZbI^Fq zL(GXQhpd9F_A%?^&*54&_Jc=h!{%~eWs>m}VbsMDl#vUmQ{Nqh$T$5!tDB&?gxRh4 zi9k-=-jL$|l6tnYuYNCu2&3|EkhK8+d3fXu8?o={`n5Qchgr=q%FZP~r~Q{$(schZ z!#lOf=90#ILPw(WS@i$9m`ULpD??nha z3Ag5++6u6Hm2~&2)`^owht1c8GQadK1RB#)AHgQ{$Tw*<42YX)RImccegfBmmhc$O z5G{+bd8^v3mG1t$#mVDsxaC-BiuN;$$&h!WWLa>qRFSaJO;RA8=Ylza(T<(LdygwY zajM9#tFQ5q8T?#wawGn$v6iz!TSBMIo3wGzgXd2ts}X;@>1g%_ow?a^z#mUr9LdD5 znyzy$)B9^0``*xgTIPg!njRAMlN!@czr6guV zn3!qIqd*M*WQxtBRIF3ruv@bd*U|1ph-~Nj^w z?w2R3n=;V{;6eQ>`=lLIU8^$&UU(GcU<5(kCX$qJc9(#A)rSBNm+g|&;>=atrw!kj~fW**mY z+}ozy^bvmsgo}zGu>YibBd|#Si$r_6WJPrXStbpbIPc3u_J!D25xc#`<)5@yANMkt zjcsrzwYEYl43hGZEv8~N_xAGJb?l0-f^I#pm&u*AiDs*7Q-llml?o z)#_1gi+PMhb)?#uC!sP8#^+&FV57K@pgox>7W@%Xopy>TaV?%GX-`-LK6x)(hG}4fF>7#L!v#MPcPj21yK%JTv(R!Hv)INPh*LnLP z17cP(P`EJUYecB3e&&^6V=Z-jTj2p@Z&WK6SZ%Q#joC&px%+=m$7bq#sL@Ke>qIv6 zQjKJ8ZSXdoGQH;A9*m&c5=}eczb7KbBC0U{2@fmBvxtM%eZFqm-+e`Y-Wqc;x-EVu zeq2u|_Nfvr=5~W#2Zl5F$ZQuW1)tKKOxg}>$AqJFG{P2@KibW#2q)w2E0pDa;-7AC zJ#af!SLm8mlIoDK_c>^}CR+?u8D9{4WwiD2GvNWZ9Z#pnC1-sQ52K6wb#+(6d}Soh zOVw#oeSnr($s*N0v3r>Nq?=F|5^eh{CePM(RZGqD+@r}$(X4d?FQ+Ci-E}?nIsdbJ zQfPQH%XipB0tK(bfUIrLO?zBObR?4Bi;eu;x?CA&(U38hes|j0*FQTnfP?QWZI2pz z60*`Uh^(=O>WE2}nVp)4z~DY`ffP zBIMv@%8%4C^?-3YxQ$?3hbyhk4;W0u7A+))t_}1qaY$zv6GhDmqs^AGNgB^|Bk;?FYDwU6nCp2GLK(LxOhm)z}6-Od8<{GhVfGZN5HYk z_8H*@lF4X@qA$D5h(Zy*KBL!OG&{u4_l1FDrcL}4-Qj*K!t!%3T@^b+yoBD|1ab~} z^LvI6{LG5trB&EnvC3sKc3gkubuWH0;|y1bRM^?gmDy*%a4&QKYUFMy=?rV%lN!VTDXDp<(P(YsrT)i@~=hxh4C0P@Svog2a^8%P==?e)1L4 z*NEJv4?YBLspWR{jKe85%8F}UtnHr$-{#cp=1pb5Q=}6l{N5yCUuoOm5xmOH8=OCa z*#_uxvwa`zKl>KxS){l5Rr_f~-9I=e_%YyT+2<=qo^YOB5Osdea#AefH07NAaP{*B z>A?3>KZMe9b5bn*jh(gS&xlIbxjn-lvtPJ;+v&)SudNwLz^wCp-$Z@qEW0lQatNrR zbc*>kW>b|0lvO_~9&0Rfr|R>~yk;?YdUaGLN6NZZxz_)K>}fDQRS9nn(p`c^-~dMu5T|?1H6ty61dg7<~_UkJ?4@eLS?sXhJ=&267q!uTM zG(1mojGYU*y?bQ1;Q~1^-|m!FvF_&(qpFwe;sPNL4XZqgvAx(ytJcI7xG4P)GLPQb zu7V6S5@SHfZv3<7s@8S*l4?W!wqkwfz}o?T{nWmex0xVtH4r%wPOz&8OwvJMf z7*Ga3(E32l+|BduacAROqZ~XFD4f<8+DblzwgSLAXSsCc+tH+SJm@Hp2sd`n}f$5xIJfE1f^N1p$gH9-Ne#(<-v)odeo7 zxo$B9$dGO`quk-2zji&P%HE7m@toWLmd`}f;G1IUOiq}eY^gmtecp7Erv=T0k}E>N znn+%m_g>ag9-INO@qn&?TpD20i!0Dov*Ro(8Abt|i@%kIvh4ovwL^fbj#KbQ|A ziE{Povl5?GhJC)zC<-Z1eNcV5O2 z6vMEg>79F>alTkcRc^77cADUeYL5^4(uVgZP{NX6*6E(f{X#G1E8~U_3yvPWkUbs{ z^M)2kgvM!0leAjYb+w5SoA+!Da>9*0Qd?Q$FPyy0#k9h{aG(V!Acf9%HY;;=f-H>M zOZ$<`Z*S!;AHhiysr8n4b5TgFhp~`E&(AW-C`Xs5Ph*o8slU z)ue)sP5-P|H|I)8z1zd?^|Di3)cR7Bv((Fmc(^9gbl$ZC7Skk2dyWt}}*BXm@9&#PCh=#ZO)H?`+IEs39m7QonY%PmfG78BuL?k_kF9FSq&H z@_fFc_!;>y?_uj~d8a35kL(nkq?(dUL+HvVg%pAXwpFCzj<#M9-a`w>hp!uV2T)M&BqHL80lc_B4F_pR`pCLggYN~gt(aSuu~uUOdhV36VFMi*>% z=#@~Frp`6m&B`GK<+MAc8Rybw^aL_RP8&h?6*y<#3Jv|rzK!jP1LW2i5OJ)UaibwV zuN2!Sv#0oO=+QL7bl7QA?apnNc)20A_}WlGx5B=}Cxssysq6rv1HIoFD9Rpp)72bO z(}8#DKJu}fUX8k&rueN|9#uZh=Kkf(t0d2;+T-d~yw`YKi;9&zm4avc;V&@z8#E|} zs4F#q%{(U3pRV5j3+bipLd!kbi+0vdCOS-3C08f*2%%I1pP8JnabV$kX%CeqqGMtA zJYjg{XH=+a#;HmmJ}4LX8sx}**XC=4@B2wRjWLrfm2}JMXsa0au#4Q?4aw*7*BV+e zpJ`J~LkgE1XTbkN#)^IxpBd1vazTD_<-t8(_FGv~RED|t>fr^_EaR1* zN5tlhXqyO?rJV4EhTkyQMC^Yv;OqB>=0}O^KhGU=J=AsLR6&BoXR{L&*l8b3C2T?n zilBFI5hzwEOS@VTuNRlatF|XIR0h?&aNG_2^Uw)qC=`jnk46?!t+m|?P;${DUji(t z6WFLC>bH{Fth>i8B2uJfKVMF}*heo(a0iZUkUyr+g_nQ0P=NfhWc+k~cD)-~a*w#G zUK*1~dr#(vht|!{%cxpj>PXi!5QtA4-~FwxEZzZxmL|DTH7xgcs~GQ~`N_z2HIa~# zQzi;0G*8Gtd;}uLuN$6SVJ|MmsiW`c=xd7-`Xr4GMu8S#4V+nIP3TB%*q7o0!^0&` za`k#E;&;0b0=B9N*RT0~Si%{7lqvjjZC+pC=JVrO(UAWY%bd2+?|fYnn6KMGe-*>s z{D<#Xc^HHL#N<}M{4#U&@psG(UajOnKrWAZEs>yx2`{v2=MzS+^Gp6PUvPNwBjKXf zhm${_s3`A?ckI&FDk(A77kKg?Q6(?$@a-3x|GR&N7>T>WKUwTKpPl{W7Y&(`o?HnL zf6MC^B*QD+-tn9U;6(U5yxH>%;WA*CIq|(@#%S4IM0h8$W==KXw9>*sVIPU?r%&4- z`wE!NKKNUz?%z^&zduPhCVC%wA6*3bkpbz{WhM^4cwKn!N|$$lKtO7zG@ILSYC?SZ zlb)zbW60$`wY66_YOLkMfhgkWC!CPBnp`Md%Dr?Y?a_-ekvj^fe(c!TTq!GAyBQ*1 zoAvT=euy^b+-!K0a0St{m8LXlFrc8PAe0;*nPswO6KMf)NlkVJ`+sOuTpWFzC6$yP zLX{^8w^YxtlNz5tPEPz_;8a_g>LRQ6_2B6#D^q;|2*|qsT?^Bvzfbi3L*6$P${33i zd>>FiKfpQ{1B=oeZ8d#H-$%-C8*flV(~_`o!0K8!!E{hLL?I5Lu%jW=t1+D9&?1-)84S<6%3kAC8QzEzD!dlWs!%!~XbM+oNc4pNfLAF0<1_ss| zbFQvzp0KMldnYuNUnLLb@TuN_{JgT{kJ$qaRs?STt0aRG7HhYi$IlMUPBTB?QvZp! zVUmWP%y27b8FIrak$5_xAx(UwpKpl;?ZKz|Rr>@yAZp=p{_ihv)4s_;TD^YCzT`W- z`C%!q0q7_Cn*y;2;$sG+Jxx_osV=g2f0Qhh^L>|y=uC2ZTVc)e(aY`fOg|o3r2=q* zYcob17`+L2&f$dJ>Tr=2uw4#!ODm$i~EIfpL~K0^OC3kl{&CYlia z+f5Gx=vK|9@(OpdW>vnYi;sV8blkBMIfjV}?BW-?L{_hT3S<>rfJy3VqvU9>oA_7Z z;!WzSr@lLie^bn3CX7?^_frOc9@>0<=IcFg>0qfjvDS1{ouapy`{$a7^npB*weVB zzhYuI=W%YiX}&=O*N%CV#`$-|t546XMNzcrLpTTsatRlj6$xfW=5@Ada`zaknCyF} zQ{z;l*yhT^GIuBEVpXnFIfqXhu~5cbetcTgWvMZ-4Jy*a3tS;@n2@ZZD}v4}efm^w?l7yz`N_*- zhF7XSB=1tR!BxV;Y~Gi7F{gASqc?Fp)JK3cel{YJ>PW;sf23pD;+JKRZd);=xHOo} z8?-rkd`XsrYUA```x{CZh$n8~N5ed+zCbMjiG-G~v7yb) zXH}o9|3^;f|LOf(JfJrCJe|#ej5aQBg(swRpf@$ZeE0T70ChemkBu?%PbdsQz@Kss zWlw^yu@K^7;LN&eRCUrmiX^UK-N=qAb4RF>)Y3-2bJq!qs<+Ob0pW#cl-_B86xpWlxo zz@DRpwT<&;0hSI+F@b9JnEO?hhir^!zx#MF@bl=~DX@ro#Os{43tObN_=9AzOa1O}7qOWnyjA#F3$}P>aTUd8KR;dtS6}o6)$7Zg z(4IIdpDQ_Nm?}zuKbx>>H&zx#`rz4GxuvZJ)jT+;Jjc@WjTKi|>)fg5O9O;|X!qx~ zU6b=qJ}>g3ava_4JP&M>#I1nWM7vfT&tl_1B`jRU@ZE|g{Ha%i#rxH|Hz7McrJB## zx(9_ud5zd#BHZuJiu$#g&?LQ1$${k2-mx-ffb&*eKWS!Hp#nkP=M7;g1ap!BXf2IM);-82Hu zPuE7l5`qw|u=0o}g{spYZE1Q}Cg4$-Y1C;cBOlRCY^Fl&8Rlc>TOWwm0)un#P(%|L z>?WV0z25G7W}Dx-5$z~AqHXM4haiqwvKbIS@kiYy zTFg{4Ae^g&{0MD3ScGm{UC|^E%o$MlEB(TK7KPX?{3-}bH(z9SYD11S-5U7{3_lUk9`Vdr@ChY zR;@Efzs)7IHjBk37iHSDIkFcP|5`k8pHz4?lviHx=DDlBH=deYwa?$;Cxy;IJ9wgl z`G7`J_MCF7LtqQ;fG;AN&Pq}Z7ENqL9L#+`?&h~DREma1EWbD*Ygi++rC8o3wlJx( zF1t$uIUM4Of)PibH3$-BMUdBb+BDSZsw6Fs8-~SzBZ6JQU(wYAA#M9(tDUp(I=kRF znKi&T{!Jo0x8nN4x{?8K3jgk3Fs{FGuK)EGwp3&v2#|)-8#iEYR9`izFd*^uh71Tc zuy2`L7DStl{xeE@OQWSP;<4e2CK14=W9Hb9Z&#&+vvEaJ9kR0V;y(9cDVxKE-u5zX z^{Mmb7oUC-{M8#EyhdX{WW<}HWXK@;SB9ogTc!VdbW1!DL8Y&P$T+im7;2Is^#l|I zyY&48>t@3Ce_%kmELJPqfL6Rl2$gLiKU(=2zx{Goh-$!3*~!s6r{yny@;{j`;1K%U za``k^V`JEi+oE8>x&4KY=uHbKF$X2ifWSZvK^G9qXFz1FOhHW(Im1a>ev={G#NX=~ zr^&%PR}@IB-9Lw*9VY?^efa|*437bb+`~^zsf^pVSfxs;q^N+Y`s@e;zIUC-Q563w1Ai37zuAgEy7*tsT`>M$=nm&OwW&d#~OmG2SzC(S9*oPit0a51z$kkDg&p6kO-6J#X z3`oiTbOt1c)c?)F)B(!{=y)JLtm?{>UgSL84)9H{=a8sH7Tuq9X)vY@oyOZAEIR6y z*Z8#o(+1=AJ)x}+d)@?HS%0_UAN|2kjMvA*ck#KjF~@QL_q%%8*@B;Botps*WqeAER%wZz=H@Jl8OHTy`{>-w3aJ6)Y9n0Y9YX zH(IHscBg`qy{fWuYrjO+GhwYURPOY2$O1Fdk-c6nz7_Ooc&TeU&qT~k-~>e`xObL? z>dzCht{pUwlU&gp$<<8}!ahQm`ijG)KU4HR8Xi-+BmU-cDopkM#rR3gqz0LoNPa+s zx4{KH(w^&z6E`BMp7R@#lB&d%@byYhgJZ;{JaSsl#=?v=_NsE#ic|19&evY7c>2v3V@Kv}XY`lby;aIp zum6nI6V$iBV_*Ams%)*!o4#mL@qiP}pwTd1C0*@qFsl0B@|Sk&sZUv|R#cPL6Oy7?jl;*Mnliv@(&Rk7l$Gb$xjfCOGSs!3>sdShOs zK|@Ak;#yl+QRbnGO81xeJ5NT%zxA7sI(V95h36U5BAb(xV;|w5aKP+BP!2K(bwa?> zs@l);hFjF(ctaN-SA?qHsF^|HWhvvx9NwR@>TkrhFdQIaM+qz$K=1#tH}X0k>1-vOPLM5>iPUF@4ON;&^^Zt~^q0X1GoZ58r$&-KEri6gca z{w;H-xW;#9&x2DocyPPqVZfr0%2PsY{ME!i(p&0zX4PTX>s^`pby3f+8OQ2<@>B0< z5!CPU<%=9SIk)5x;k=b@OM8c&%cqM17v)H-*qDx|S-{BB=nax*b=ZAbl6{7Vr~0|| zpNR&d)jkpwZDB>OgG(Z zr@`U8eV4e*y`~$Noy~V{@|grV5m)DDLv(ooPD3!0JbE?MfXIMEtj(7U7J8=KwpDv(Z=1_Ix?1J0k+dh;t6rAcPTQLX={|j+ zsK)*-M8wfXraE=~&P{~}HW$n;tKonXur;lBsMExV4y}zyzcWbx&hAGjEgw(8_Q89m zx0{uuLPTx{q`AFWbMp(x3{{#cfIMt!sojwfBsmsXFn*}+Wi+IBWHZO&WzFWNnTv@@Vg2N3!QK8jW#FXiS`-ON zj%=X4(bg%L;l47dKe%19v0PFc-eHX()TFz|6X3F0;XJ1&yv3Ya3REI2_B6<7T469# z@KAC!IMrtM?HpCC*bcFgQ@64#H4^;n%vI9Zc3Oe>nK#;)13AVOuB!U&XON&iiZuWv zlLz1-en$@8q-Acei#OLbT<5(Dfpp#bDy4BT6@xAXwFh zCAH*rkVFvN(R`f&x${<;un`J#ZT@hNf5q|Kz~ZoiQud%yZyjse413lqk%qQ_v|tXC z_{hm#w=T1p+Bw{0EBPkylvHIpKH4gI+?DjWD}c+-Uo2?7(Ep74uEq&ZA8p>rsfwdU zz9Cj8nPhI=ePK0bWjOlCss+6tH(sn?LtD+6^Sz|u|;lJF-mL^PpgI_zS~_QTTOe$=;k&Uoylgn@A( zwaRj?$%Stkk?r4Q{dV;uS>(JI2#|Q8TrfBP-Lozh3r4>*@{X&EIwn`{b>rkhkIT6!Nx#7{lErA4Jk($Ntv4! zTp^7klURMfZ^*d6NOw{!d+l6l=f}gA;@!Bgl{EasT>Q?xD%;^@Bt+cxki`2#^ zWwh3A_X;k8evGavN(mev-wPXDc#z~C44H8^j7|}uj&gCB7kM5cfb_|Xl zr3;=_wF&F1`i^}LV&vyCVWpMWPq94YB)EjFJ)qS#YT}eLZQJVY;~j_$Yn{|{;oAXohm5j*<{9PC$2*fK$#|3e=yTTg6vt?44DBOst{~$8m|8tdwFkm{oSZ&1&l$sbn!*liSSjn~ z`{Tv^GxpVm-R~-Y&N@{rdHcJ_%eZG=Sn@5<4S9()#&_i6gQW2WrSk=LaAx2(^w8?w zaA8_F2H_=JQ)j8@`O#*w!LMuINqRt1=sDjB<~vQ6@|X{*R(-SOed|U<4RR4Nw(~_3 zWYy4dV10pCJiM~D+)|-F>7{);zvijMJLf;QzBEBS1q~tV86uGu0zRw3Wi^AZrecID z_u-!I;YMP}bYV4|7;n9zn46bT9{EYp+h;Ly_RH6K9qd}5%(i1l?DZmq0Utg9Y{sOHh=L#LkB4*WUZlI@ zWS>y@7%e@>?Q#nl>qh5L&k=S1Z8 zT$_jy&$eNF?({Q574^ok&R3$5_p!N8C6^}Ti!vVSpJ45G*&OUSa6TyJ&D^aal=Qrb zGkg$bQSc)<#WpW?IVfZkREmnh-!f%4@7%J5ojz|hVK8^<;mKNR*cY_6BPT5$=E)Nl ze1yoep6yQrJkpk4le9V=RfmEltXI_Go`V&$qLV>sr#*dC`^UNh?sqMJ-PbIm!N2c* zyaTQoJ{CuQQw`P-_dVCuB0kr=R9D@J=A)X9{5l=ragIn%|M-2>((;FNVfeXamEG$m zWas1jS9^5LtkLIxU0-%ygeib1n{oo|84NKS3FSKqczY9YOjL8CQ2e_-ANL?`YON>ZHkEh|fKRKSVG(cZ>ADPv?*ic~T`^tvUMRkEEr=wx+=dZH z-M}LvB;`kWB6a0{&=rWm*>j#AR|nOmb&4uDwfH~S=`1cboR6}^a~yqxIc=RB^(_?M zC~#xh$(h76-`C1Bxzhp_fw^KQlnHTRcSt*tzxp_k5iOF+o@aJUs%i%(Ert|aD;jF} zOb`h5ZV!8h7@g&>Q@0JSXEogTgf0h@ECOJHeLaYX#lzMma*>HA{Py^w>4K_sj{Zvdi_IgJMmV(h0X)mm-D+ny86-9w=DabfVhNg@ zo5*xJhhY)wtS7%Eksjsko(pv7T>JFh_E&OU$jpT*)wdg&fs6Z0m+ekwtMGM7!v;(Q zd`cE!m{s_=)pa19IM_LJ8fYZy;TuOIw^z|Tw#Jf~1PRgYfjx<#QNQvZR+bad`kX&@ z_*6@~6uvd2mwYt1Nspzs(s^jvOSDuMB78l|t5Wg$%FazNv}BX;HOQhu)WxMd?nV%d zcF?%5{H2^5$3=8hx(uyXUrzqJ5G=tBJ(rBGrY8~oY*e|GCT2SytLMyeJW3x#dn{|T zWadt}pPt>#G84L#yi7T77gBy#&>@{D{}VG|O6S-hVLQaE*3IX5Lesb#^Wq5Ta7RvJ zXGl-=DH#o6U8vX#if8>!3$M#lmM`xk(EGyf2Lt9NL$?=UDs+C(IZJ6%o-7_De*_|k z^qpo+wT;&O#5MBcw?8qyKA!K3OSX0oDinM1hJF$<``(joEq`e4J#`oW^K<*?wBiO~ z;*C$bd|*jsQ}6rlxN`p(Dodd7EH)nSJ|Sxg||r!ZBcz`IW0A!&Ec;ijY16M$(RkZ4a7j-pH2y9Yzdi8I+*KdPi1Ym6)E#QKL` zd*wu1PfQ=RyY1YuK4TZWjYfXY$uDZ@{DiL9Xub)AQ3OD2oVN2^tWSr(W%8a@6=weJ z^;zQ)Pvu7hfzoLkM^hgUK2r~E4=G;F1+4hfW@=X5DB4T;8C(SB(r8C;4f91uHmQ~k z>q>zUv>Mz%CW+;{qQ{{Mif7wHy*wkdL=#t&eSvs<>|&YeuX1~G_B`}}hZsE_Uj)Be zQ8%oL&{`8tycp;0K@Q_kPLyWu-;HK&8qi=0jlcL(6|I&Qu_i%r9kT(H$(fDBrXrzA z1WBudt~S)bJMZAtF=#XJYeV?ckyu5<-T3=CwPD#?UguL4Fm9>R59KGddBNyW04=5I z3`&{yfqnobNrFZ_>UQ97uT!d>*D-b+$R!EA^~dX2N|>$4Yp1w7ok+7@;5U>QF}r-a zeyQ^pufDF|;rzMIb$N;ueF!R|ikL{h3C>wVXXLTbRWP2(3l$0UKGdK)li1!d1njoB zPm;o-jS#kXk_`yU=eN}qc+RyjuG5`jRHdB zgntM<9Fu)lJ-bw9a?*NbKV0Em!c>U=8N$xV=p=d8xON;5ID1gk6-K$zigdN9a9UBr zQQv~^^y4Ih_@H@8fNy>7z&5A6j#SHjkGJY0>z;X>zFaX?o6J1|4{mt+KE^zQ-J2a} zBliLyNcrSSpj;uh3YS0yHRnKd!rbE9xov)Oe==9@<@+-qV>>_W6ja*(*KK!)# zVh-=#mcFk4kOC6XG8>5&raIw0^{#-G3wwkXv7oAyTt_>{-Ve4jF)`h3@mNLedcV5{ zr7oA;jW(B*Q@aj$Ouf(gzt=k){7-s^%g~6&vvEyO6zm(76+IX0NDksRttttOG5ST= zSL7+y;RsXTJf~hY75lj;^z;6(Qe~g-EAk*Rzy;Y&k0OI2imt%Xt-)kJr+f$emnmq! zDYRS$WV0oP=e11>#b-{?q204WR={^Aa$763T85Z|D>i@NiIKam73gj2V!{FrkBY z9!ct0=TiT0^^dIn8CHLk z)gQh3|CY5HjSv0?+q}?#0G&y0&@vh={MA-^&mP*wNm4Hm_t(zJL-*Yy-|%=G)Ei>& zV4BZ<)FXA`)MkKHneOm(Vx?%w+5Ks@iE`PxFS4Rf8f&-y9Y8<#?=ovo!FtL6IFlw| zu7Bh&MXLW}!Rr47+y4O@{+TK#K@v}krwV?#9Uc}e3Sd5>j7KY0F}y!4ZF8!U)$7hz zJ^eXvbk#dx;?cm`^)ZJ{ty>S{v5#mfr3O1@EpD)|gG{ir}%V^rh%w zxw@1`6zOFjTgOR>i_i0AC9k~bf0OB#Yb3u}8R#%U>&6fZ=*Jk4ek+nGoy849{g_P` zM7PcEour>&Kt6f$GayM8>%*Uc!A?30fXK%1qArcBsd8(d((`>k)#<_RJc%kSz}z2+ zZyQQ9e=apiUx4lMpIb~t>VNS)DN|QBjNVo01Cu0HR1?sR!{Ra2{r#|A3q$Hj5I=$Y zWkCh8sZS>47?6_%-?W9nC)qJkFZXvwHc71diP1Bx-_;EkJJ&rcS#LV#(g!|yCd)c4 z-s{Y>8}O+J21M#m_o=PuS0`_}Z(D%bu1(iS5S5ArKn#pNyd4H`XQ4Mg#sL=K6ARJb z3xIsE?+R18g;lk=@v0Bq8cYKm0s*YX^sa2`HjL;Cr(Y#O|MKhK7*-q}K@&uS&(oPx z2O%F{K9X0C?@fWOC=A#K+dcH>_&@ynBR_w}&maBqM}PjYAOC1=|Jctz{=*;t>HnPn zXvIQ;n}GlBkw1@!3O?>W%U4OeMreI(vGhSAcfB~C>^?Cd^vX~67i)j!^1 z0`ssk$eN(I4&OA_N6Jk|{(mCf|EU`8|H;JWW5FVP+>UM%I*+48Pr&F2`i|jH+DJZ- zxqFpZirZ9a1GH%Vm&MM}{ zzumG=w1s!LpzZ=m3am${PL{A?c8MBi@N_?6cpQ1;S8^ofzKn4|| z)qc8DP@V=~hnu8O`K!$-uk6KkpThvAkWCwbD8I*egt^Tr7H-IdQiL9`O(c^}xK9?* zR*3g}2P$F(xmiC`hnj*ehp1v!s^(o2h(V-R0$;!roN0hojdXmDdcLpb;ES;R%=a|*cxe%HBssng%LbWYDO zhKz4nj?ph1LhzhkHzRr(S`&Zj-Fmy! zaKn(uJaN|1X>}iO+pS-7rXkMZ;Dr-+Ez(O*^K5mff-cX2W!a|88I~{mF6RTp6O;r7 zKcFqY_?yYHp&Q^lixjLzU` z2XYxzkZ#yr2yC(mvf96>hFviif2&Ug9G`KSou6N~Os`65)9i?un5_@GFBjl}#<%mK zI?tKPvX9Y8&+y*9^do&-g+``paMS~`iGovmV?K0LLpw0FqRA}nyPAh3g;;A`hfg}; z5NUgPEeJ>nK=EZVoS9)PEoKyqE`gTpimVP|t5b}O-iSKawl!GEJL0>80%!5JzMM>8 zEE}4iu6cC%Z&xtyI*ewIMn8?{9^&_xQ?8>CUIt>>m$5!Fq_oETQ+MFE)Sfiq3^bBi zE!Cs9;~u+buX`q`B#u5w;ekNikh3TWO+t{SF5@AccjcwAN{Q=?uc&Xmzra%uy3ePV zR!@kU#5yOhIo!36kbJ$=xGpUL#OMLZaclk%?c~1reEI_R(&x3~ zv&_JU5+afBzpaB6u4G(_t`9)(#f{vlK6G^f{ft0!&`!a~BIQ?QhT@I&i#JS9(6a!| zu^vbJ%IN7aP=bbemiW)?2*aEp!UKLcBaQwQ z{G23eY(=kx(Q^_Is6~+I)U>am3@*VYV?eH;%y`6kre6-@>nSY0lAb$nke;~ok%uql z$NoORgggEJLudSd2R&hVIUi6zr%V-5Q`J?dHO0nl`vpQHl%0R12h9?1L~|6gTWR3! zJA_{FpxoVP0HFE?BrsvP8ABh+i;{LgrT+y=_}@~=|KBT%!0+*y`hS3}iU%@X_Tuo) zWT=cUwGwW0yJ5Uq#60$WeXdH1KRp^!y9Uie#}L@k&m%>BvtV4G4cfs*T(`;Q37m3 zChoAD1br`AL%UHh`hb?u-d4jzVvwWOExptUh^c7Cam+bH%MspZdrkne8z4Xa!|cYy z?+eFMpyKeYdBI>&o64Cr^;6YjyCmq}vx3gdg*es!S&QK6&pirZomhn&V=K^O_9#Lr zg>rPt92n#>V;1t5m^}5-iV~;#Fw)6qiu!+Q5$%&a3*OA6 zOEO~doC0G=rJIoXjQPij#rDFkWm)M51gmAD2Ym9&`Kw3XP%osOBiknf5(I?>Fx8PJ z%fK|Y6PU8q?YQ8wDv>Ye>suR>ENiYxdB$#?N%T(oE9KTb>%I;TeF;JE)nVA%b^sZU zDd+YR`+HDHVBs)LzwPU&moq;nv}-oC%!)7besFcMKA9{k^f6wwlhLM=k@VRfZH5A< znh;K00QYZ4;oMa79L-i~@i5394USVP)ETXL@TWQSMZA}h z?sk&;&JhOCHO5o}&O}$~f@D}X`lU=<<_C15(-ZD#nZchjvEwf<8K3XfxOJ^H8b4yA z^y4)@JvQawi2K=UfHa6&s5gMfBK&>5ANanzS_aSTf6?V6p4IKwl+*V`yR^YDV@SDh zBGtH3WThWfb3 z2e@Y3t&xsBYw0G@z5^ss{<0STS$?bu9mf{a2BaDbyQ z9wwyVwA=SZU+7GcZ`BQ>3!#B$3c%l%+(U3n%Fj&S7ZFtcoo906H%GST(oj4XNDY%y zV`=wnKw|S;d-j`07sm8`HRN`7Z2BgGwT!GpHwROffH=eOJbjPn1|Z$}qokUwGtt)A6e4XfuQnIhd)Y zvT3uZeGnc`xtX}w7E%JgH!Z7K?<^eO9FI+?)|UFW zBGUa|JUoc=Ke*cP(cXTWVYXG6es<2u{pg)_Ne79ATz4A?;7lE;d0hHcB>42wNB*Kt zcj{5~m7&APaY8+=ryLIoSpZ2)ZJa<@HhpTNjb+D{qHW`E+WTjuR5so)dKUJ$N>)9! zlK!0zlG~n{b@CAEYlN5nMk%bFD~c#9EA?+{^ox z(=m1r)ToNh_=TRSWI%!5D4SFGL|bZRp4qON?YQ}O4CPuANTAuix!~cs%V!cKPYlRg zJ>T|2B1VRL){;|Z>1SE4%emvOCjY>x&pA#0uI$m zsRn<9HLgv!*tN*Qpgz}&15&*eU?#0!|Dalgf3XJruk?KXEoJq8sIVGu0Ns9fJ~#y; zfUu*X?|f<<4aDCraa$90orYwE9tQaIn*Zk0NB^5op9lLV8A-`Chb@95qmtN%B-4V7 zLqaH@ZW;Yi_J@9S?s#RfRMdZ@0P?*fQ(^nh$6_8W=th><){zbpZZcMnln4P)O{L*O z3{*4oH~G`;LBqS*lTM!aY~6CfW67N2FrPb3%LjcFcNIEKgpd)4^PIP+py26ZuJiyU zyM+vR*(6=cdDbu_>+`fJ)4STq8nCl2Jk!$DJhEt*_nJYUD}8(SOQ1&n9?t>$FmVpA zomqeApC`;PAe|zVaUC#7)A4PWXS#<`Kr)Ij8GS*lkZ)e~vu0;kXXko+nq`o8p1LD{ zoDa$0T2@@~_{o53m@r(0k;BR2o< zYL;5b+S&PCuVnpJE=ajrbRosZe^ZTmotkoe!#?S!k`F?7=iARfe-9Zx=PQS|24^MfZN># zdB5IjGM?3Hxp5{f^4t8K49=S`iSNC@su~caPwAtUKcN&tEJ@l}ffWU3QS>0fHO65J z&_wRxktb?ffx%UQi}fwTGq)o(w~AVua5QR0ND=+MRHjB2puLWnmm_Bh;KJ>VUF6qpoW)y z`SEk|x8Qiotdi<9uJEF9sk`>rDYh?+{7H#W;`6^f{Y-?ulll@a= z32ci>B7A4k?qeo&Of$@xmCST<4t=DZv9d>zyd7XG_I;;W1<&lJZ7fE_qZW$Xcsa#* zA+kC~9PYN;`7|dc%rQV~lUg?7`Dv^wXoPXCtx!}$;G{^}XAzP>h6}D(Z7xEM*n?Qykd-nC;XHue%^j*^K zQRf}U1_hxS!wMv}WK(fCoOa0LLE}e%ibada)bCTGWv0YT@YMy`TWXcooal3}({!dMrmMyq31_xajM!?nULGevJY?rkQ6-JMr6@;=nu0F-W zf64WaE{}cZt)KdUo1)#L7WOtH&7Wasfl>~XlowXsc+ z#q05XJ0`siw$MnE#;UIAo{*s?7tiTetu@eSmIksP$gmuWL!M>J(f4|_k0@sVvkkV_ z73F}YGIAdFfkkJnvjEdT?!@q1prNPR7@G7d z!qGD{ZR$muL;t1u3UY9~A(Ag!a9eCm*M}HeJ>p~*;$Kqbkf>pGp()MMi5%E-M%-FG z1-)9Aq$LSa0&wJ5PK)UYpAn`5MLQM&rGWU?P1PDd{>kxU@TdKFz3`kys(FT zNT3En62z~Ojz^Q{{O<(H_o0+YPpT2g+69YEi6yqX#(&j+P`mi>gTQ^=X96bbJO1P&{UG8CMlvzY#0`6tuAzN6g#8ucO_ zie0K-7~G=@E`o%SeNVMJhY~Ev+4+=D?)`V`*Y=fj{296?DNlR2{(mhFyuMUpTy`s2 zWjlVGM`0Z+#U)}S^dK_|T@1o8Qw4vd4lSsWE)Ce5u4OQ<8^MI9E$OrB{ee~d*XmuT zheRqfb$iduKjXV~;C?M@)C{G=J;ixP04!L_7`{w8z0#JM9W{5EeS~Ly71Fo9P{SmcE^IK+g=zQkfNiC+2Zu9_H=hjb%4*j@^C64Aqb&g zHUrOw3e9z_*cm*%)!fk1*3kTy0Tt6F+c4HF8>DevzE>YV9C`cNa5+i(YYL_P$S_g|)p;3V6G;C>Rc<0ceBry_qy}M-s-Al z?V2IQxnD6jL#hh>$f83RDF!0?+gfnrH67YBbcC74{W_@mZlZ)1daWrU-Jp;Et&==ra2ODI18H38A2eL}Uh$3%ZKXx`?)7hr!wt+wt2C!f3bTnsr^pZ80Rtxu zl2XNx>DaS6%i;L%H*eb3a`^3F zZy~j?9w>Se18z4&@BpASFTDXJto=kVTK87qCDP48%SO$MK|ghsKAx!GMo8G(FUGoM z{TcP7uP{Dv-mvvqe%w)~$sTo#OgF9HsqMve8uy+1@j6M^)V{~WNL)(d!#L4%pu;y4 zPlL|LTX+G(^}b#a0l4?QgA+-Os4mRRRZGrmhz~YF0wxx~ez0JKk(}|f^}V})XFqHi z6BZb#cQ(7HBs){^?;rTw^y`6If0XfH#%JJ(4HN_=LK=t&QD$=B0!MPe@R=T3dfE~7 z(1|pF3N@)I4OJ9@UNkx#@}Tiq%9q`kw0z5l|A0Xi>oRGW5&)=PAMN+|50tgm8~JFt zn9Apvn|R>Pfefn-arPdQ$tBt4UmJJ&*wM+YEoo7U1qdtjo!GUXC^Upg7omPF?d zB#8;>4hES0FbeX>+OydEICaW`EvCXqWWK9JoTH;U+bX9p-CR{pu5lQplKE0q#^yRv z_JVu5i_q6Lty0+o#K*!H0O1Oh#IF*wez>(UEJIC9=hE9swV%f=4xjijnqj%*O8@vE zLq|CBB>3|r8Ty=x@+olU9@VCyyG&)6#nDB~8|;(GZkd0jeHEyFpEk00Jq8Z@_T4GE zUs7uK!LhqKhfXpLH%IBAfcZ}xhISPQrxBtI8j-Vd(ze^R=hi3h%7|Cb93lh#M%7(v zuvjx-PHDD2F$ z5LPY2jX)k^KV|09+ZeAo1wlwX*yU57(3gQlqyOiwGAzp zrCs!l@kU9S=jqe7jVy{Q%Q@(K%9dR#VH?>KN@p#>Eq@I&~TRCJFlN1@0HZ34$*s1 zM~XrDVQ2cCIfceHMZWulgx}h!#KZHaTIk-f+Q!=MzLh>sp0nTcV!y{9_iPxK4>=k0 zrO^GJYlHAB-{0oP9&wOZYx^Z^Qy1FRyZ3eja}L3AT@!hnRFfPcyL`R zHZ9;6N_yj8JRg4@a8iMb&oV9cBpsHf7Ow%N>jMdvA@d|xLm@l zyh5Ao*Ocv-Y2Daw!~vt4NPk#)bt^Htv?m;c-?6QGr%--7W!6I2R{pT#Gk$>S z3-uQtU6Y%I{PIY=)aXX7OG?w}G}3@g?TQTH2!N%RfEz)*!7^o?yC_fLwnbncOAIPq z_@f!C`7tCA*dnB#{nY2cH<$6vn|y)t2?oNdyNtA-Qya?V zT}6mo+3A3vO$2jEU7MglG1th>@fQZ;=%DpK^@|SuBq9blidyd%0O}1vn<@Za0{vzm znS({|v&bOOYDhQ2p}SBcdoJYM>&Ef%E~h^seHCITofL@y5#YUPe6N`P)zG~2nWD$Z z9btYpNStoS7Tu+wdbQE0`m`+8HTEsKa#r=1#gVWA(}64e`$)7qWItc*?b$D(dZz=M zvu}u=^SonbtGj9WRJ%UpT?WsjIX#sH@4H2 z*X+K(m9Pn58q0uFfv)^|sr4EO+< zw+`3P4wgYHFAj>f8r_#81!sKkvS~{{zqU`HzFt347QC|8C>m$&_ym=qHKHZoIkK;g0spGc5$GH_UTUhzSB91O`QX(ptPk?AKV zI9~NTD#~}B=&Mm?{W1+sZ#D24;MqveGEUi1r;&P04LCUDC4?NO0{@64u4!yS#vYt! z4t3`#=eobUviCr*xu;TNGQ;w5m(GvBEnk%fZhl{I|7I#-m ze`vGQR4y7agvcqpTN-W`|a1{(7OAbEMDe!@1x=a-;Xvri&;zSJ6Fz`TkKM|WYlv@ zo9-Ey$LJkXoV5Wqj6Vv*|A@2Hkv{;0Lb#X(V`eVksJ>V~z*3HP@Hb+ZOu{8px2wuR ze@p{Vyoe16`i2v~g&e4LABL2=(aK*{H@hGi60SQEyXOuL0|Sn}84%y1&8Xx6SZe_G zq)#@CpB?5)tG_XhJi_#*82_*+>iqD%wF#@gZyaL%Wachtwol6VmhRcqI2}jyNFJsi zk_wgsUhL$@$dNp^W@EL*Xn%4PJT34l^!YuD@YcxY{4W+N10v%0OGJi)zGmE!(U5@H z*My}i57;)11Z%xZ+S)@+lOyaiU>cqbwTpp&FMSj~;xvq1Ig2`o9DTZ-jCwezhSab! zOb#oM?Q!Vt!4XY94fcL2A!=sg)%iV=tp1vnh{Sid;4Yb-d%VPH2mX+YY?TGb^ad+@ zXQg+a(1QZQ4e!vsV&6Htt!GX#&st?EHH~5<{6ilf_8d?!PcKQS&3p!2Gi%C8%&UwL z`U*9QGBj1h>VX~q1=FSsX0^8kmYG$~)a2!*Ffv^%-n+P5merX_Zk`ZOG7C5peu(EN zn*l^Ic*EJ;A>^4KTs^iM-60lvmbmUDR}fV^50{_X*hdzBh-}k*vY{%UEw~yiqsCj^ z!MalQsNU%9d7$QR_lmQZfS*p})FVP@LtO;nUru?yl{E1j>6{Q2D{jFpVW zex7y6doO-+>*2l@n*_&0RMlQ#gEH0)VE2CoDa|%vV(892D2b}yEbSPSgdXOw$qV@7 z??f9EbgbrANd&%7H=)F`5twhXRUiG>3S@oeees%`>6@zP^EItQ@`5e&_9VKCfSG~L zs54doW}hv*l|>eBs*fOJ4zg|IJ9Xee{eLxKtXqbuC5_2;__lGy2O;9bl9Ab-bZUZm zdZl`fV)Ov({sy&#JB6xSe$#X}0z!0CrHh&SCqK#dF~)-YMB<)L1tli_B~_zSQn3I$ zi2Ij;mgiqQb!e&`E5aWs#mNF(5S*BaWz78R%+=P_7aA zO0jRAfOwrY9B_>AzSB6#kP;EIK;J{3U)3KtnW@XJZkE|W#}OK}sh?O6;5prS4&CU4 zyD%YY80a}tl9?F!(8_Jqky0!G5@|m-!`kh)o8UkBD_=e$EP;aQ zd=D^Iw(`dw;QqE|+p&k2yh%G6y{Jim!nLNc{~<{gdwT!&f5@%tKLzTgsXlxje&wB{ zBH5e|s>oF?DSBp1=ppeTWtjbx_}F$`INF8)VOh zDlgw-=ANOl=T$Fvf<5j20&-|yFphC@5LfBmR?J1^*vK+wv1L*zagE99}5sZa*YSsOI%%nY&)AqR`i!$+@Y2wh=FS2tFh`+B#& zxt>`Ss}i{+((lTc~2_W;cCA56cGxV?FZr3!yRhQ^r+x-f$%lb30(?ES(x4Sm-u zUw69J*WT+I8#e8opTp)e6746y6TdE5&OFlz0Pgs=q&lJaUU6n;Ai1(}oI*c9cR7Iy z@Pkb=_Gct~wI6(BIZQ3)-SyI`yJ9?Ih4{Hb-B+8{LIl@vJHT}giQDX`C@j;y1_;Oz zpetprOA_wm-!$9|k{G3ez2i2XoHr!iPrJA$U+_ozg8`TZ-JT}hV1^lXt6#)BHR-xt zMKOvOPr=vK^jnQXA|u`d&FuNUgw6I_mhuFkTHP z;xd42aeAKjI9hn-J6x&E(Di3W2 zRwFcN@tvz|&5-v#+(WG`pMI2#GzMO^8Pn9#wjWuC;)t`o@a@NS7n*&Qy>dddtd<*V zAPa@CIx!NjCd9kkSWO8N`-J*9SY)cxy8<@jGQB=JpfMC094X#4clk_YX@8E+vl?5T z_`v8gGf6>=#$}c`a!_Kwexs7y@Bam1RR;gGoWb3(2=upVO#3>qlzj8CJ1+6~JI+jc z%lO-DV@c`>mNY;pdjYIRPr$7^<>ctfIJ&|1&GyM^W4qAs*6?D}oMQ$PTZ6}QtKC%Z zr&uWAuL{5WteFXWY~nmhtAq!`&3QpiUf87gMoXwAiwvy}85^M1CXGWq(3Z2rn+38gH*I zpYDGDCAwlghxqARxWvknyRQaNA&+P??=GG&x7UrieA*$9f}M6)&`u3T%CF0*{6LNx z_7(_(gqYRsz8P5iXa~8rPwr6He&2F@Vw5}4A673aMudDI@nRMl3qP($UeogyB z32a00Ula49c-kd_c+v|t1 zT4=QLJMsYO$gF8?)w)wl=H)Ttclys+fny!c>4*Iicy>C@7;Ht85W~P5`Pq)!1*_MP zgnq@nVpMrhfGGf!o{>y8U?d3MMcjSm*nTp)_&{*ypdq&&97J zihpM(MLY=o2?HU!Aa$6Rh>Nt{u68k6`3TiioMcr2_aM5>b?TRnEv0PjDt0+z8YJ8w z;Xr4JdOyWQnIyw@dMe< zu8C?qor*OA%I)1nSsiqcGysP1nVv>m!BEPQ8-g1*CQW79X^0${PoW7>t5hS@WoFY# z;{39eh~XQ_L6-+E2QU8u$8!(U%DPAgRx!u$0{)Cspzdr5qFX`Wr=^`hjm3NKY<6^w z0?iJE*1D%;K=mhqOZ5yJ&Us1j0u!D4EcywO4eFJHHv^R#WLq>EojLm24Sn9Ix_JxF zkb|yQunKjG>tyLSH9Db#Y@mgT2|@OQCAEKOxJvugB&WWd6mO4${t`@3tv6uG`x zL!4Mvhz$C4EkfD;i!ovl)2v$dsD)OR1l*5#nA(VxhHbvJJlspqILHB?M{sY8C`||3 zx;H*eUn@_g_5k-P;2?M~rT585rASYVWBmq60OEn2-dk|1c;^o}%7$=qLdn=;oeNZb z?qnz=v&h+c#Ue1V^wEsRAAG-%+Nw*M`YKV)MGFC4fHGAuo0YWg-hFh6DR_1N{i`r# zLZse|Ym`0OGRelyHK^ppP3KzAV;PAjbCSe8A37ez=@$S-_!s`g3);SenD|JeVG27**?CRa4sx1)MS*Yd8^^1ZsAEX7RNli{125#C)gB(~^n#)S#I zEE&byPp+IhZ!8-U6;ZN&$*r-%cOS3o7rg9dw0?KbZvI;kX65am(Vv<_299@9N&hfY z0slZxQo>b>Ci;6II@>@-zwuL^?5Pq!@8o5qpr-;i`a*7YQ< z-q232DRK}3UydgLqDsX^Wzv*PsOCd)(W z$1jWb0F<2sh$r9}mcx}DZiWef3XJ~5g??9@6=fcr z9RGFe(BeNiik+qq50o5JYq28_uskYpzR0$VUNkElz17~(j++cqbMwz{i~6i3vOHHB z34VO_tVLr|tYGg`(k5Wxq>m8iOFnML>9S0mWfRMFG#Ya+s%1NG zG4f5@GKJ!3jPpV-&)|G)FT(hdorHSBZXk0nf^d=zD)nH2g%9}40PFH>x zf-zWXXl#|>a}>~^GEli+LU%LzH!uBDl3$b{J4tnY@e7y)n2_GK@J(Ywx|!A@T{vUE zfSs*VP0y+^9XvEEwV8r7u2~*@pfnR6aW;LJ31R4Sa`A`ghq}OG_%mdqs8dlLZc;G5 zRYPBmo@pOnT;PXFOS_m&9?SI+o_l=V2FU!PS1wExd6F%PW?W?6rYC{Zki4{fqJOr7 z18(AkX>pW6e%ai*QTw<_Ax2}{(_drejZybe1L}eZm45ZjdFf?;2f~{J8pF=`RH3%(=4*(TDVBdCcoX&em_`f}&Rg~&iiu!v zp$KhzS|23j=fuFiA7Hdq7$=iNEl1XG1x7kLQ-yn|j|SvIq%Om(hyMbfhL-_NTo&Ga zL6#JkHyKyz3V5;iIv@?){VQNjbG;P7HIKZgnW*w05z4$pWC=yu&fYcauiH)a`Vgkd z!Tx2eR6-G!7OTHp zXu^pF%nuVK5u4tXL51_ah?tbrJI(fL_TrNdyLsGhNMIef ze>3#=xLC|e7eLcxi+VE*=|^Jlf(y#DPZI^+w2{GvZK0vkjZ4`DD0i=gBRI(kAfWY& zXsqmrqwBqAmY?~W!h)G9E1S3vY!}E$_Yr*?qaNMrH=ix%bDYTHss&%L9b&2xYeE4J0O@|6T4JS0u;lFNE=%q21va;ufDnzpX)oa*2-7Itq_ zq21Fzwl0RT3=foen2dKWiR96q<8c6%rvEgY7^)p*3LinobmJuR>ZVS~N97CMWLf*q z>9u5T=3pK+KXY~7_Ie;j{vi=?prxMSDpn(DY+=TEi#!Ss?GI%GySf+RY1k0*0EEBc zm6b+_R`LVI5ocn_QHt0-Vx&RcX@r5`eN`D?(2}GT1IFz(MvNykB>EH~=2x}a6Qe*K zN5$sLWmQPq*g~(!QwYNA9IuC$GTrLUco6wCECbBRLmsmtOXCj}xn1KPiek`MZhpkr zKObGMOHs?xAdM~qtm0#q={=z*FQdZCtyDmL5E_&)ZP+g-+)TTPC0G27%kSCa>R9J% z-rWDropBvkj0~!wVox_)=Z9yNMt>1Yl$%hM1X_P@JF|`*&{6hLX4nGhI#s;wtA-{r!s~Tp& zN8u0e#br{u7b_!G#3qIV8ID_WR<6~F=8n?oZ*n|!PK}THlWMV>Gn8Nf zW`D>2N*tS`-OrV8qi9$CmM$J4>^7si7&muGO+Hj!IsmalU6(tv~hT z)Vw)}u4`N>9dpqAD?FuSq**0%NPpOs3rt`2;{AP*NR#O`r^0-|UOL%-fV4Rmdi!Ht zdrQ6jJ+HPpTx;6Ive_MbO}(2gJm7FX)6f4f{B)VFv=<#PPl?vMHD`EaQ z{+iz=m9`tzoTB3SA|5A=oR`;=*IWH?M11Y_f03{9{|*)DzvUwNA3`lu{qo-DzFW(= zG~XB^URv-LYP|c6a)FX`&aq%R;pm40ikZ*&Y~Ywp7V8%BJAm>B$7vgTvMwsDV=f@r5R0KwK?=y84ED(AOz!FO{pPRUIL;)vzO^ zdt0vmj4|Ry(2L<_ZmFaHJ7jX26 z)To6w%4tGwU4qYjLj~$u^BnIN5*-rXCN7yL*>qIgYTSY~4gnG@AjY~!J08}6+FU`E z&cIpZtiGbA38%FT6Wu$bVF?-P0~eQLE_yx76w~R|u~7aZFPr{4-OX+xc-o!uiWyJW z?k6>1sk)H(29hK^zB7XfFi+*4hnOs5N_}^Aht!9nOz;&?4#>TY%O(kx6+u(XQ<@3s2j%Z=l7Nq$|C?d(I^}@T}z6dE*yHQA;E*b7RpQL(9B2g1Dx~@pl_D)+}Y#1R7hAsaKsxMj~43V}5>F z)-9X%wh!fxGf&J?d53M@{Q!%+B~XJm9@Ed zrHvxud{G&u)+Bz$N)dzs+H-&qjq3qTlNL1$fR5w^LX?66cmQX|jV+4dHH!{onQl$V zw$05g*DiTa=Y5;~Yf^|mH^|=Ud|S}+S=o=jOuD;KGzY@;c3+`nE!{hYeP;2~O_KB2 z;*W-Nt)hSF7uaW$=STXi6XoN)V>LZ}J$4Ttm6Y=hQm2AXvJv^fmb^Zwf^`KOtKXk_ zb5v;z^3kJ7@B<$j(guH#b@)W~na})!2h9)%{8<9*8$SpO1@jn-6hgtiifv ze2&jC{AO);;yKvJKR8)B#f+xFq9r1EGP-#K}TPA*Y_0eTyio}+n2i9}~J|B8cyT8gjSA4y?r@shw6{~8la z7lqmAb|R(ef!u;hXTM#h_dQpANhsZDHEBCk`1STB{K#hNytdAT49{D`^*lC_fX5d= z00pJNKmi1g{CvSrM;Y4-5wV`MoTM`u%M{hJn7y0z4b6pJW;n0(#f;JOB^CT(i0mup zVTQ=h1ey&NO{x>GNheny0xo1>yj3)9XXY*pD6O`W`uD;FN(u!N0@{bms$VxTw(IP~ z$3A}hgAPg6c_jDZ$3BDtVT)TVY$pLRdE#ta&YQ3YNUj`hE0H1)mRz8}-7s*XdbZ?| zlS}WZ!G`y=KF9glOAQJ_XQb_eRC-9XJJY6zxx)mou{0gmHLpBjEKcjUAGQla3$La| z`WCO{w3-$C+$DWGWqml$_tZ;k#q=ISv7?4y&@f~n6WoCA4xS#O;5LUBFp{fz06E8x zbdxSu8ucMJU^%|8XnEe|mQOLRDcu2zPdiS3Po-JDJDBx&U=7tExoO1;hhzHyhI(8( z$b~76kY<_ZTgxU>owhh(Hgey5np$nfDucxj>(D_s1`M+STs%v6PRo&xyuq6q87Hlg6I5w_xw0Ja512;$Ia87$Jr9p8H3Q*7m8 z+5a{BBp;Yy4!shcOtGMzUx2=BJ@SlgvAAJk-bJDaH@=4>zZt8yj<6i=8hi;iq?{f( zAaE8Y(u%z}h=g#*2tvOB0EY30d6oA5l!f(+UI(I{6+P$jutx@$C?sg!);Q6yl(Dpk z3$xOGHDk8igEp4D{eb7L!tYSVH1i0SJ3^{gNo*Hmo?V{k?-@~QFC}lZjcf!5R{Mtb zM?KJ}mZ`7u4?Tu_VCFU5c69FOi6t3Hwpbg(lWr5A7;LO-P>Rxy<(}!Jby0}2_r3C6 z3*pqs&%7N`kG6WgS{`_qUK_jelOxGJ+DS11bH#5am%~LJna@M%3U2hEH-I8zRH)%m zKY1qA{LIO7E-qg^n_;!8ucgy(c)pkV^Y8=s0AV2;B8rqm4#NbHD$L@Zr(W;KBmw5* zzTI94J88tAMgQG%>&JzzE1f?ZsiRf>WYaO*hTawa_M|fnx5>-8#a3XVXx@&@&@ghK zb06%eaquGS_@}hus0jb}Zd354z}tS&AB--(w|bYfZ>X@jWL>QK@Lcbzj4TY$IxKt$ zFO;UE(Rh9OUU#8Fj`a_u${bS%d}57wQARmGSii@h^{MNeae_3_@rvb-s!~Dh8?h4@ zVAo9aX8g@WvChJwX7q?2bxr46=pLEzn&}td?x8&&IR5jmc9MB z)gT0V4Iqdy-3Z<|O*hmDIEW&VEE%i+29UH2qTcaS*^rQMx}s3jg@Si#Di~38J$@^_ z6`z!J*`yEPvGEGgpk10!N-wFGm8&m{I>MZ^p@k=w`aHcevW~;;7h?RwgkGOdEM zKTo5FJ9Ss;#W*uzv+q_-KqYv9S;ecy4597sbv?o3JD++4-w-Su!e}oF?*-%RN#}=oVULT$>G3mllqGw+FRtt z%!BedGQS3@71IVM6XaiY1r*`6Ti$-JK4`VX@9|p9N@`*ymdnc>p4Z`2B2RM1{>395 z$i7$%B@+bT07m_5P>#FI*6gc{c%WY!<5;bU?>Rw)UBaXVG(eM!8bCQQ|Eljm0io!-+~Wy)&u>6d-PJ&55F zSR;U!5L3?P!_khUw4Y(Jy4|#BVT2gANigM0b>p07U=8+(b%l%~zA@D+di9j$lhBjp zma{J&4SkUV*2yt2ga@;mu1-P3&2*y#5ZZKE;AI)n@1fOHqsq-FnpYjJIop_T-^e45 zj7(6b;xZiNeLdgSnnx4Pci@4~dmVC7R+w?D<2VegF1-XF~X5J;%MjJ_k!o=s2A}<@?XsH5 zrGC%K7xDM_-#XXDTaOwhq@8bna#3(5m=}ETYm^+tC2qYjK<<4StaVZ{a<}Z+T;?w( zlLX~yZiSnH!j18dKKKSAgf!2zD)m-G7+AF(gd~6)EV7>*tP(tg=GeBwO_bdlqN`BU zTD6m=UA3DF7GjaoxSI6q%~oe}>ZTAr3i?@wYBGWE>!cUTFi`SUOB&Xt2#m3m-#QaF z4jPkh(3OXHHe?#A8zR=vt>wFhywl|kimlEbW@7( z6I4Jp1osw?kPsix5I=gcXr$`!^I3{>QK z?ovSEpja&~TcW|)Cx2r|BZ{Ra%MtA;6%!a3HIiX55^>SW*;y(%>iF1#%Nh&tg8<|F zYHTa~;5U@#AnE{MWs4x=$83gH6{~}cwu2t>BD@j);=Qe(Ib-=&{zjs5KaBT8$naxu zP$z6C$i)sq1im2yt;y&}IxqUIo0VwtXa=$A(&Ei()oX>#PE+{NN^_Es5`k68`iFm8mAf?%5QN7#Cb6b zI311GH{h5nI`BgYOBawPHeou-Xg3M`jZ&nI1JxtVMZWoN%~C@-HA6rC-nPaE;wsgB zdX(p$+TO0{5YxR~5gH2TKmo>X2s(Ju);~O$lhH3J;zbwsAny?+WBEH_Z(aTUhnDei z9l2v#LN&oxsO5SBckG_^oq3shlSBGOU#1UHlFsi=Z3Q4oZZHIc@+&v0k;E^5#7D+> zZd8LAoO0Lyt33U#3oInuch~c>w(RMwznGDn=BA0|C!C8}oKBS>C z0SHk01-dX|nIO%ng_=_DyO8et?)$q6cW<{<=?YQQjUM&HPY*UkWv-Wh=8CSf(sld> z3K$rKZHaLBN53$#r!83VtM3|*{d@8d^3v8dbCOsI%p&eyMFf6YBro2p>WXoW;^d{A z_0y(L=)ah-40bIF0budiAaW?pS{N5ybHI0kuJe}W(qenP{H?o#c=gD(!a`HpOciw$ zpPZ$^SoyW#co1Tm4Go}M$6CR*2Ohk89^`+uhPuxI>a=;_+jz|H$&@GN0?y{7v-_+evKHpxO!P7y8cxxr!W^$}ix|FzxZ-T5Mj*a?g@JFA}B#9?f*WY_~N@)4AF8)fbH!^pn2ixi$(>MQ|q`cNM%gup#j{EXgiSRPn>h1!t0a{1>=$4nm! z5Okgs#)F505A44t(e!37{$gU!4-Y8r(;fBh^1kh{?&0wbDFjR?#QEHr`RkvJ?8V`wGQ5yeg(wOx-RU zW3H7a>3FU$emLIweEmkGs;;w*)q)8#_0WE``deKsvPS{gg|4u{M!$`Y7OKx`YSM0+ zf3{n-n`Ea^SasyG`W@n!KlViTO`hk@Ma94(m>&uz-Z)2b1L~tx^8v9AKQ!+To+#0a zDRxPD--O5VM@rT_=L`oQ+1yV3^eS8b>^a5E+op9BtdRr1lSCbwawc!8DUMtl>!E8U z9ODE&Tq+4cQEtZfQsMZsm!ySRC-0`9aW-)uqYA9JJA&qCph8;ljgpR}vB8aP{pQ$S zP3_!EoZW{FPn~9cP<(bGO8U8BS+_fG+^WmAc9l|s6tki6lRG^O+C@7`vx0Kbt>#5P zJ?|6GwgpJMd(`I3y(&K+)xq%sbKE#>SDGqQxnBg~Umk^46m)*)iLUBrK|)&BH#&yW zU)^mQ`60G4RdeIpx7*+Hl3$;dN&K+&vO@QzO3XDL=Z5`qI%tDed4Qhu01?KGOlr5y zk5mfNUeC+7kxBE!$mNIFIoBu88~h}lxO6A}LUd1ZcmHPxCa^BCNYAm4&73e1S3Dt( zZZ``Ofun6X6G)xQ&tK(`^YicLTgAJ-Jt!-f!-}|P{W{`)SDjftph7v};<4Z}@8h^o zzBH#?ntMx0*7DfI$mU)FV=F6fE%KWdfnSk8*z(bzll zdm`Mdh7zPDkbOEOP7QC{#lj;CNZ!MigNSJ(G*Nx@#IPdj33W-VCz|7%*QshUf3Kv5 z#_g}$*ibmxQgUKz*0XNLU7WeiL2a-K7iIfwS0cG&MO4B1J8shQlUh%KZlckLZ&I}x z>~Rv3s`3}5ZtLBmf$k5B8I7AF*_kOuUceGDB8Xj;m>-ikF2uAvZlG8DSbbma&;<{c z{+I0yJqM%3itouiFh@T4teg4~ONMzpV+hj}$XdiEMnQJdPMb0j;hRGPI>9#*@>`RwOW)1&vx6(h5#1+B2jE>dRgOn>Aq;aNdt z;zkErfbKN&{dlNJzH zqVboFDXg(GD;pBfkZr@m;oMCTY0e{ehm=GE`>O%2Y~i#4@|s)1)tQrc_Rgs{L z3pA($nI)nUP5iFz1u~YSD3jT4WvRM4Evv^6+~LB{7=F8h#)SpLf*kCkYNEn?o>Hf4 z+u=_j%peh+c?B10<_R8yoE)k$(dy9diUmNN>tBo{yVD(p*UPs1TCbZ?o_|4B-sM{L_&&^nM!Oxb0a$^jYd#*T2GVO{k6|UUcorTuN%wM zXek|6S?CkFnJANZyj{A&=!N7t)WQ8|(D)gmB55oXVW54Zi9Qn9{-Id~Nq1nYO(?*< z$AyjKR7h78#xtjOGwrgZ()l-Lm1gJ^#I z_lw(_W9y}fz4(%rWcZF6E>$uAEMI*En@cP94bBxBx7*c<`7N^`l0RiT*)h8zV3d7J zwj(!HMG;Xj?cfnT=o-e8{s7fwW5rb3``(fM6J-_JnaNIT$Yy-Ru{OFB(V_@^WY>8u zkN}Qbj;5B7N>qneVv7j-#hyYGTU*154~?jwZ=*&y&p7UV-!o?PPpi^;C{8ojc=}l% zXO@CC^ig9Hw~2DbsF6qR;6`!CM?NiX`Sgd8hfV!hbt;%-pRXb%+hDZQ8y}%D!2B~f zBO7VgnPLmWsCZUo@H-5Hv_5ZYIVGV_!KO>0r)l1|Hnr!Ge)t4OwANp2l4LZ4qkjf1 zf;vg*?;ykkAE3a()Cq@ZnLBNona#O$WF5I}j{YEfczZ0MzYzsn z{R%UYyde!nAfH75ZQ2&|W+tQyv1tR-=tJBPcJ<$d$E=}5(8N#Mq28r-ZeycG0q!DI zRf#^Qzg=1yQ0G4BG2?eXXpOws8A+0Vs$M28E^qb~SFJQSy9c!jT^*xNcKX4D7AB6b zH^eJ!2DZW98?^8B^B}c*p4TQ#cIB~6{II|^p5l7THZhB?2q2Br96zRReMj|S zK<=s%5B~seCKt;!*`C%P#yCNf?#w*cG^DHXj#e|EYmndJzW+AgwE;3d`czp~&M>Sz zNuX8a%*?FF2~6t-?bJpKPxQ2OY+EJGr4u5|7$WyA#y--)9&uf0<@PduZ#_+1eU+=& z&(|Y%bl&=9Q4y1AsALZ)$qz08C&ME&NefyZ<=w1aa~&DoiWOga+*!mE^&`&zCWV_? z;Bvrt2Xmv=up~C!Uxn-XCFctWfs>e#X3^j;gzB;mco>|Mq0RVeLJX2_ljML1E=Lph zym)Tee)In$lo4y&&{5ivktHQ->)X-sk#nEQChZN& zJ2W$nB`GxCKWbF(cxV$Buyd}AnN|XhPA_sBv0=r! zq*`2c#VlnAk=~Q$8l5t|CNXyRSyJ~UVc4tGBn$G1WiRVN30wXf1N?aAltF}!A`k(-q4avLWPR|Yewm$<5X>0~r1F5;!G zQWh<;efm5Z6W@3~&!A}8HZy}6>HKKHU8iBC$kDgPs?wLQ7#8jL zApdGAqYJuF(dA@=_(m&=bX)LQvVIPEeaK|E+JhNB(AQl0Xw4Q~X*)I9nrK+rzPWBD z{k;2Gp12^npbh7WrO9K~*!FI?;rJTeNg3vCjH9EC9y0`%3G2MqJEGxD*eKmo@4hXM zKmX+6>0A*Yadc)Dbe<8aG9y9m=+b(js}W z(Nf!LglrqWGfocSDhuj{d|6ZeR?dQ*o$OJ)d_uKbIzi+?H}_2nY^{q-xU!#{yPtxR zCldIPZS9ZU#+w@;p#?$j+Af(Gr#ltiQcozpcV&O(3ZKzDeco@&a{Kp;G6hb)q2xm? zNm=fu`J2-M^N`mS9&83xIgBq`jV0>Hr_M)R^EVU>3y)=Gxxj=K_+5yV;VWmbYef|1 zS$K;exdu0biLHICL~ZaYnYOofvo-mW>Ms5agP60u)%7TGvi({4XYyLA^aJzOuX?zH zzXLGZMMa!$ImnPeJa&mL*@hii*>MmY&~@_7t8x$>@hwt2{mI2Wpt15C(%En-+d2<9 z;pBHbW@`(q>FE7Td=OtC>>&MO{a~X}F`VXeb;P6bybLw9el&BdlX~Xp96~l3kGHQd z5WAqM`IFyijSP=~ldog&Lv46?o5}>dBMlplX(5DVLL{_?e2eU2Qz(aXxHINE_QRiz z#@$aLzg&E&I8@T}O8Ob9&cDot76>BWPg)-l8Up_dBIc%@8M8y+WGJpk=#JctNA#K_ z@Zp^eir$k+O!q!;zWpd-@ARLu$;UjGN5vQ%S>(e!k(v(L&E&;c;;=H^UA}EXSGyjD zEty1y=oqQ!HP(DJKHhfWY04Gf{;Cwb7F~#WMkrS{-I5H$RN2|fw?9W3w_801 zyB?23ThwRjAf=jLUmK7-yBHRFe`w7n#|3}X3gqczSlP2a${V`AXl5)`n({sP7P39v*7vjv`RGmKjq11X|j|RVomDXrE&twj8>9^T)CQP zQ^0$<05P=m@RN9p(0s~6^-m$E6{Cy|Qbj!SpJx52jsC^t1%DdMNAm$8CPuX0?eaC6 z2WbUVZS;)6Tq#}G?#Ch3xwp*z$9}&L0ElObB$rqerv%w*$c%=JQfrf zT|lfwl9i62qO~@c3GRqTvGymvEer8ZtSatY-9d1$@w^PVx*;d# zmYCnHMFV%~;4E!x788ZzZ$3+hjBYE~2Lp_|a7goU8bo0+qr_phwcfrutOlPlZhR$` z^;}3J#OFjsGjm+dyZtQmy|T$1YTRhEByy~?rupcR??U+M{Awa6Ovv3fI8naQ-3L(^ zTcmSRzA*)K!Gbbfv!98mCMuw|UC$q`>0xlB5>>5)LVn=fy$(`&N*t6pkW#h;?R*pydGdS!)DNEOWKTP*>DWpwyWXe!5F(|D! zNOa5YOR&e>rM1< zx1ib0q!a$4<>S|P*YQ(pzU;;K0*lzqz8It!#$|B|3|uPv;5<}v+Z7G=2Z%?Vl`|MH z5MtZVRVhY}wMZz^!VA%N-BSH6@t#@PwAmZ(@3C(2qc*o2p2)C8NvQhglNxN}m@hB0 zfRnB;_)9$|OqYk`b!e$siNdmjS^p8I1^c?aCS;?5)KFpxf!j(G=A3i5-Bhe6MV3>Z@+Q`lU$5Op49@ z{rQW>#}?76poe^rOdBB=kkD;_n|yv`+qmRT8#o~;k+G!rh|wu8`n{qGZe86Ap9EMg zRrbxR9l&{77w$4sZ|{Q@jPRQ1G99i`KxfS3#2J5jsOdUNkBdNXGM zT^l?ixqT984*d9xaSZbT>IOcC5zfPbCK~wzQ@+Q$cVZw7JU_Q2>0o;$@~p-Xwnfa> z^T3ZVuNYH%H_>0Sh%ovo0B8RRGnmA=VRi*{PXVa9Ea4Z^sg>_BC;!`pLn{=}U!7s~ zslb&G;WS z{Li2L=V|{>_sE|`{%3Fh32A>K`JV&q&$<04UHSiEmNq6uVQYm}m362vtzfyTOPJfV zEwE8ldl{;M;~G6hZ#`xk;<6EZKyi>yHA3c8!h!Q0K^VQ8YAo!hT3?vk7HoKJB_!XE zu|RxIzGYz`BA2#5{dQ^e#n6Z!g6arFgMxqr{x1r{XQ03S ziN&6PDO?SuNb}D{t`ISix*jACgInpQqv{RDD+RH3!^id0NU{l^y98VHW9#At1x_A2 zaEU*Nce_t;4o=QRiTz@N*8gH+2#6N^Vv+?ZGKWD6Zfma$C<|YFhu*XhWo^RPXE(+& z1c0#q;tm|7M4>l9TK^78G^A-U(7u3%c~S$$xSDfetbC=)DgoV^K=z_DK$nMh!wpMM zHlUx91jLd4bsR|3S>J-}`lhQW^}JuqrV7mr!VNO+DKz+0Zg7w!f;uEzdWP_Ge+=}_ z-i$zho{nR7=qep>(EFF`lKj_ef8##>1Fz7H`|mI8UoKspJ5ZuQFF^QTuk63Sc>Skk zPGhcRC;sKSF#me(Uo}=Aul>2He{Sl3w}bwy)IZz*PfY!92g0A2`v3l*vS^{3|32}B ziI^z52QkCoR;1~`c0vyk6S0Tmq+oQd{Rroxa8J+he?X&(q!QB(DwV3B>$6 z+zaR6l{@t3UI)?R%qBo(4Y@Mr-VJzpKaWoz0%K}cFl5Q441BeR*_Q%!CEiBi8K|tT zDe8FIBIFuxPQSPEbc0m1tv+*|#owj)MzxtACCvrJw6ad^M7ELnQO{Kwzj;!1Wl#!5 zW#>j$^aJgx@cOhPS_9%6p$uuHN>}DXqyr76QKP#gV-P}8n$l`JT^z%6=d+r9HPWS1 z%q~dHhFtLM(J*^aM={=7f2FO*9l57`!fWF=Ms;S}war&>{m~g%4u=9|lEMCz!VDv8 z(Rnc~lKd!Vk^p%h5EM5(q~AgqSUv()>tOh$(UE9}2Td*JX;BCL}q z5`cE!(40sFAuv&KC@*r;tXCI(lSm3OtW>-)1x-G7&#CF@;Yo;|GxYCsx~+@b{WkdP z<+<*=sK+(ozT9iY4K*gr#R)ZoH;FHvKe))2d8h*oAyi`4YWM7er)|et(BYXZl)T6` z_cbfxXx1!@f0_FDrfAY~YQ5h(b+p`PoeC#o{j_t+G6|Q@#TzDH_2P!>G5`ZyoN*j= z4orH2P{#nf9>DV&hy?LZIkZ|^5Bb*VBbfG7;jiP%JBP+n6%?&F5%-d`bC^u$5SlqD zw&$2%G73I1-6ga5I0#V+LL0qZAXzgdwmsIhH5qI9DV>i#7%pPOX74?Ff4EM>yu1Gd zPMvN*L6geXWWlJ%Es6SM(AOJ`)R09)H(HE)&)-7MAtd|1Z+$73iDZI)iSemF)AICl z%ugoK)^kgykkqz*uJquwRLB|uUMr~h0!d}@{59Lez#LK z{@^9=Mtry=41A!<79)vhpf>FpJkTspJ4ME|Vvi`&rM+h-%VIf;mz}QE;L=waN5)Q6 zyceQ$o1L7uK9=Qg!&_l9>(?T{5DT8b)!;fO(V>zRrLSh=blQS7DE?8wC%)Hj#Elt+ zAo457+>|PKg|%UDZ>^T&tSX<#i9_p!7da%Q4?FFi&Nq;GScrV7nmIFPMM^1n!x-fS zlYZMqcJlP>tlkb)qqcP~0~iItFviu!9v6#!O;o4nbame~4czlOXYh*YPQvqIpG||+ za7qF71+8R;@DyDR(6Ni8AQj?4+p!1~VpiPB>iyR>FOe~mvA7qSDJeq<9uhy5xpufr zr=I-0%4Zu7J5#r>HUR&!(+Z!|qK@ys-N3mJA^_RAG<7D(sxt-4TcT@TG~r5dGo9+6 zDY-h>s*rwkG3l;c(4f&)z<|ojn>lM{P-EaIj1`3_q8{wOLf1n6c01z^Ir$Z3M1pZm zFZ)qfTvG|-wt0Qe{8E)oecLCHu ztQ6e-6AhJp`NSr_##ri8Q2cPuqW75G;JYwcjSqR1pg=mAtM(u3Q~o1Uynh_8%j79M zZT44Tys%l7$lV54?F`a8`-rex_^AM=LxZhX#g`#BmXZppOIE!%Mxa1i~kvVc;FIe#wx^YeZA%30jB3c_hL>SEDnA^18DrSfG)2! zgeFRo3nHpt48-Nlhq~@SPLGwTr&i-)3|+!kl{MIvB(#ifdALR$Tt9mI&=TrA*uO3N zvAR0M4PKhFu12AoCPRrlOEa)Yx;gg4L!T7HJ6=29zGIcxbIkR+^yZZ9+1BT3@ZbU1 zs~t}1uC9;JupY{(V3jy|#%Wm)vgs#UH~P~V7v)T$3G+WQ;kzvjy^{-mQ}GJ(P=2so z6rhe+!KF;GuPVB-fiA#3UWX@a`_-ehK+E?ZY6l$eIU*J(9SjsYJ20;n)YL;GWe#Az zem>bCj)|s&diLPTeta|F)3!Jq9Ysm*W8KN?K$?h0GZr0~19QH!Tu9A!XJ4BS3=kCV zjWM|UQ1xS`d-?|u6mJK&V~98oq=5-J`Ac#E?ev!&lfl^`jg0Fp5!k|hYEk;RIUrSH zoNnZD06*=QsQ5&4jnqufj(7QHsq5Z`tK4Z-;Xoaz*-x$FmhL7iWk%>~9e%agyZ5M^ zZK4r-E>{gZg=*-HxV~4}7r@q`GOj?ir*#l9%t%D~m_GU?3YQ*A@Z_wpyjpfxy zGrXbD`WKQ|WQ?`bm1GHhJ{Fb=efQO?CmTdI0pM`lpK42!3Ygj32+tI>mxD2Nm3F+j z-%y`$f2h5d-S_QD8#!lh-R@%DkJFZ#UFFD9b08XY9Xr0)1!1kA1r^gQt?zF)p-m}z z;T`dB(awc7ZuqLfTMoDE2!QnB%bsTRy58V)S7@#0SAn2fJ>j6%uFv&^RjWO1fMj!E zrUVz{fu6*Dlt!5Cl6IKwmmF@qU1ZEvt6WcSo;(WSRAkqZjZO^wlEf+bz=;l6e2phdG$%W3&r>lPQ?Wm- zEGdLbWcBAba`)37X}{at!OrLwNr0Dnp$Uko(C}s@8d^BMRM*Fc)Ms}7l2K;=9%TAp z2vkYvZ{6<R(m_H%>8ttgA@Hxq@uH_?+xRIvfveK>w`Mzfq^-l7Rnr+E>@ zV8UoGgTgAMgTlgO8>Q$o4aJE4~lT-v>G|Cmzp{_#c4qG;}&!MbRjH znX%en%!^f|IqgX?hOt~I7#Y@83*k<>0pS8*YJU5X`z0HzVFRw2NYGK{HuUJ3(UGxj$^#VEi)BOy(bQWE~E3R(v2Rz1Xxphiiwtlp@L~3w)4K?=4 z!!hNeRP{-Vxm&=<1EoX=#ebmnLF^xB)C? z8;=Z8x<1YBm`Pez&>#17Oc?9ue*c>LV@w~#|04{rB0C89vR3?JN0W4WT0|;vfTPf2 z@ZWt+4oh;h5v?Hu;;*W!^hJ}Vy13pcbA3GfaL-on^qcu8du$M01e{By!JU$#>d+{N z{1DwhIW~{3(a;oX)ihEfUs-d+#^{*-qZGqd!2p??hFgn5vpt_gwu5vS9B21LmT?@u zJaIzJ>Uv+dOU#rG&zU#{a_=ttWPcJYe4ohD7%(4~Op3d$bRwhs&;m{ga)!}~t6l{3 zJD{2Ry7Bx>Pk53!Ed#)&b=n?(vn@$(%B*A>QLH{tkhPVzFuHNy>|G;Skz+Y-;WlO1 zA^7udWGn#17j!a|X)2V5Fu@gDYII?71+w-s}@teuyiV->746FS$Eb^(DRbTOPCb zVDrr+1_$Vv9|XkUa6f|JYOowoWe(lXuU8k=MhR<`_y-UCoHog|B!5yG3Y%~Kl6b#` zJLJ$&33giGo&&9i!JbTlhGVO)0(uk5d{p-=>HJyg01v%(f}368_FP@cUnyue&9%S2 z>0Y_Gur5`z1=pgjQ2l|s0C^zyJ@fhbphNx};8CKW8LmkIjW2#@*+cz>=nFLsWuAXq|1hB1yVhTeOG9mo}9) z5!QRR&4dq)&aEZLj4w}^0aD2qf*5q>9lU(w;|Mvqv!TS^&5xl((c1}^PBkh2P$yKI z=J>(5CfV}*{Oz=8d0tU=-XId^>@~^Rf~^D|%ox#ID4j$g zUm46!TO&cEQm2I~NA7d??&_CmzJE(~f8`Q0kjq}EcihG~D*51%vdy7+%!3A~9+XJJ zG0~+#MCrs)aPR@TED_iaCU&)@q`j#1F``BTh@ki-*$;7R*?a26i5cbV&yNT%a80t= z0YTa;I45!VOk_0FwOiNMgDp%~>aqINz4dkc!l=7W=h?8QYxlyHQ4?I{KMhYP$^94? zJAu>Hz)r9MxqJD}DIbzdCa=4@lHKfL7|JhJb}e1iwcan>9pS6P@_LKA*GuGCFePSP z@2(U^W6wCan^0wo`px1PYSZ>h7BC=nwe?FNJ^QVP*H-U0>hVOXHz>HLTc)atA-LNg z1}Nz|?ND-_SaDsq-r=nL@r#Ly-Y-VGY~bV1J2tb>!hP#>&&wQHeqLSOkxPB}Ei3Ww zg@}cdx$&1mWkoKlJWz9BAqO%zy!Yhj_kfI;G;tJD+@IG+Zgo$12WqMcytSB}jw=Ah zhxbOEFwEMjIg^~Q`HXli@D_attoL?W0tpMe^bFQaDDd_)+2*h@2Wj#`+9>t$GutZO ze#e{(6$aEoLB{}7d)@hG6`iZ*K2F|Szuhv+7uU{HgfH#`l+`^Gu{J)t@7QB^Qys{J z*tj3r-KMc|pbUH3iB;3;TD@etv*%TuQs_@U@DjE6y7EZYj+#rt&x;Si>9jDM+UOj4504%NmcLIUXAZ zr$5+_?>Ez?C>uoi)%h7L%^EHOYNM*!x|q+xXN|ozI)>+>WsWTv?e$g#RqOr7^4$gDE}=Tm zF&bKSu?TN}MSVqFRiRvfH=?>axm{o7?+wM?bZ?0rRH2p2Dh#yVX7b>bgm9o>w-JVw z_{HS9e~*WK87_c2Re($pKRw7~dbFo!gt3{+fIOEVh2|B(rqY|OKRvitI#PYbNvFz_Rj-55EA^lyF*MMMYP`xdc z)VoO|miKWh#AycYQTS)Io`9vU@PYP;0-;ouaC|u``{9*i%J-x-#e~kHV}~}o`=sBU z&gL^ZD!7$gMi)q;%3z7oD4#mYT6JW^oiVnEg1TX)(qiY@5j<4GL%#Mygie&RYqztF zw0%pe$hW$mSQ4QFLpuqqFeb(<$$%~rnkff5n?bq=#o95^+KBb_4aJ;>r@n{O*HXv) zDAO9)*N%Zz)|b&oJgO6#XNx3Fb}TMgLxEoptg^>*HO>+&i#EEK<+CAHEZAFU4rpYvn+nUH0YvwoyUAd zQ-r(DTjwL~spX$M%kIiP4~t$8Gm<_gtr0*4D~H7csIf}zU8WoFW6`d0kGopN7~B;5 z)X1vEyLGSRBN&~7B(c~!Gr5R?yP3q9xP0WSlO)&m3jjkeSsuA2I13Af*6@U(w1~;| z&9s79aY-w3BhT#<4XCY>|kMiwa5KTd#9$X>H!v`&3?QBHDJHCx`78@OAR1P zwz7^r!s3M;OmmRg_AVxoup!`QuD-$!BzdRN)#2g9gjwtCL<86E@f;@|Q;_MQf`Ogk zP58tZRfX&l|ETUqgNXr2J{)xpQpft_PF(`$&-|)JMfVnX@WI zVn9IIQ$n4mG>4LlNRiQE`V{34>Pw??LmQc&6*5e3Om--3UKoAeSiD?bTq$+u!m$MS z3v`wLDsImcdAW^HZS|25j^$dQrMm20Ko}_}k)nL#wA=CDN}~_IlC7ruC$%YGp4@oS zULhUuMyG2_b#T8L=K>grJe_->RzXQs4>TGT(JVk$oe$04mg`n8j)}~w9!mQhbW!8v zx;4Bnfcnzem3r?)$ocrl2MQ@te!<0{#{>AQ9@xW-7HFk@9;NMOwY`CvmS&n?vh&H8 zdgtd?DWECSB2b*rd8~Wx)SY)0%;zk$ARLTID7!A49B5DJ$23~x1>ru{3j|A1?xqD* z|7gmKz^Z=h5${S3;JbCuwFEQ9P4X?{+r>t5q(Qr^f-VK5gBU{gF?b+S>05Ug~ zoSLod&@+hob!_0n$%RK3=O*;{tDa;x&)3+ub)*7Yk``_ktMR zk}L(}>VkI3V>T_`vv#t>+lERfG8yg-LI=VJyWEd`siECQEm~mqOSw_LKtlQ^P{juH zBRDVpGD)1tz>&lgGR;qpOG;07;dk4;|2TWfPLMA#i@W`D@9h&F1chUo5TE^*P?uj! zz}rcVQqTsE?jfhGkT?h^L9*AA>LMi-i=pGg>fG?Qw^C`ETB$cC``i^^Te|#)m%E?GWvzUAUfy zlnq(q6WW4K>*%AnnH+d|*Xn%nQZp~@7t?Gy5BEx1a|Y`>56%8ZH8n}^^*+=k9<}i( z>BXMt_nGT#cRJTy){n)jP+j+nG!W4H8{yOJG_-f=_g_pBkJJK)O`ZhPA!3bi0y3Cz zZI8R%O86}7Sii1_k!~exCrj=vUTZWcrd$Yda8oj+yG`|8y5DQdjQ#6*Z`iNiYDpqfoh>Gz+B*07BV5R@Wk61|1s= ztsK$_f_x#E)>XxGrq|smuQwZ*Ql0EjR;mecK>sj(=H=YoKe4M{lJAbUD6Px>l4|K+ zE<-jE`Ie}6oU1t3m+R2+T`Tb9S~kWn&-S-sdFcMMpm*b?bwH&yWSWDl99>x5estu= zd7i5y_e-DZKUcr-N%tILRNYH0z_bD>BA z%JHzrS$&5pUi&Ve};mk$Kj#-fz#-}5vNcf{7Cy@!1LU} zei6NT8~y7a$!Bk2+M2w&2t3V_OTmBP$ogf0km!O*>+>DCyWSy|HE~WVlIa1*((OF; z=PX<1nBfMdm+rU%(3_2e>My43Ab_wVtf~BBN)bS}ex{`E^RJ;9fKi5~zb~`Tj{V7k z^#MpWXJii}nu-HLu2ndOH9+TaDs;lPVPJf`w+~1$o2^ZLF)DLHLH)lGYRR)IyYj#m zVV^Mw2rP~Ubj30e^Z*24={Bf<1k=L-{&?JTn;qR)hLF`W+!7Xapmz3*0U0J-l3dZ~ z{EO+z9;jh(c<@D0Vazp~ana@5p9}tThyN^zKb!7Pl=u^e{~R3urla|mfBSi_F5D5+ zfl?$#SBq%V3;ZF`S;dCwhNlibTchhG1dNe*YxinK2VlZm`(ED0_^Gpga3#y z@K5O8fG}_lr8}S-NMZXZDv9xG^eP(fEBQ_x+wgK{&6vA1cD6WNdh32}P*DT3Pvz~0 zuJ6+!ala`5f@L6Ucmt6AJBz=wh9F6D2?}HldThV525s;~VX5||{eQvsTQ>hrb3%Wo zIT;|$N!~`cR)aK0Kpf4We@D~HvZo#W{|jE<7R*Cp4�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

      kWX*wl>a%cCLz`s#p& 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 literal 0 HcmV?d00001 diff --git a/docs/source/images/cloud-dedicated/vpc-lattice-access-logs.png b/docs/source/images/cloud-dedicated/vpc-lattice-access-logs.png new file mode 100644 index 0000000000000000000000000000000000000000..7bbe0a5c27727b10ce955fb263c615e7c1744f73 GIT binary patch literal 63202 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 literal 0 HcmV?d00001 diff --git a/docs/source/images/cloud-dedicated/vpc-lattice-metrics.png b/docs/source/images/cloud-dedicated/vpc-lattice-metrics.png new file mode 100644 index 0000000000000000000000000000000000000000..5853d2dd203ae536a215ef9d09432e0ef970cd95 GIT binary patch literal 105477 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ξ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
      @ka+R%{C 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

      8N1OI5cDR_ieXMG@C|tFA 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 + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/images/get-started/qp.svg b/docs/source/images/get-started/qp.svg new file mode 100644 index 0000000000..acb4808d9c --- /dev/null +++ b/docs/source/images/get-started/qp.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/images/get-started/super-routing-1-dark.svg b/docs/source/images/get-started/super-routing-1-dark.svg new file mode 100644 index 0000000000..af4bc9a20e --- /dev/null +++ b/docs/source/images/get-started/super-routing-1-dark.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/images/get-started/super-routing-1.svg b/docs/source/images/get-started/super-routing-1.svg new file mode 100644 index 0000000000..6c417ece8b --- /dev/null +++ b/docs/source/images/get-started/super-routing-1.svg @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/images/get-started/super-routing-2-dark.svg b/docs/source/images/get-started/super-routing-2-dark.svg new file mode 100644 index 0000000000..45d85cdf75 --- /dev/null +++ b/docs/source/images/get-started/super-routing-2-dark.svg @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/images/get-started/super-routing-2.svg b/docs/source/images/get-started/super-routing-2.svg new file mode 100644 index 0000000000..2ae570f87e --- /dev/null +++ b/docs/source/images/get-started/super-routing-2.svg @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/images/get-started/super-routing-3-dark.svg b/docs/source/images/get-started/super-routing-3-dark.svg new file mode 100644 index 0000000000..cc6cea31d4 --- /dev/null +++ b/docs/source/images/get-started/super-routing-3-dark.svg @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/images/get-started/super-routing-3.svg b/docs/source/images/get-started/super-routing-3.svg new file mode 100644 index 0000000000..78e84e9e5c --- /dev/null +++ b/docs/source/images/get-started/super-routing-3.svg @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/source/images/initiating-endpoint.jpg b/docs/source/images/initiating-endpoint.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b391c7d5aa3534f7701f85c6d6a3a1da9fa42193 GIT binary patch literal 45232 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
      >w+!cGd}|(qO}Hxl=D9M<*RDEy!2T6U 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 w6IS^r{`2|HPx(-PtGtVy<8~^|S literal 0 HcmV?d00001 diff --git a/docs/source/images/router/cloud-router-details.jpg b/docs/source/images/router/cloud-router-details.jpg new file mode 100644 index 0000000000000000000000000000000000000000..965810919bca38ba2c08a2bb6316596ad82d4e6a GIT binary patch literal 81251 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

      km3$(;dqA@)2_t*VRmtT5Tl0^ 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 c_$CPEe_H_hf3v{B0$hYzT0o+OiCjbBd literal 0 HcmV?d00001 diff --git a/docs/source/images/router/cloud-router-region-ord.jpg b/docs/source/images/router/cloud-router-region-ord.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ff8ec6bef30e43eafdbb24aea11bd7e5f52d2520 GIT binary patch literal 74181 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%0A{{G%s=8ChM2Cou~0e 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 literal 0 HcmV?d00001 diff --git a/docs/source/images/router/router-endpoint.jpg b/docs/source/images/router/router-endpoint.jpg new file mode 100644 index 0000000000000000000000000000000000000000..bb341ecae0587752bcf51c3c154a5567fed40c77 GIT binary patch literal 108435 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 z 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 Axc~qF literal 0 HcmV?d00001 diff --git a/docs/source/index.mdx b/docs/source/index.mdx deleted file mode 100644 index 3ad0bb4e8f..0000000000 --- a/docs/source/index.mdx +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: Self-Hosted Router -subtitle: High-performance routing with self-hosted supergraph runtimes -description: Distribute operations efficiently across microservices in your federated GraphQL API with the Apollo GraphOS Router or Apollo Router Core. Configure caching, security features, and more. ---- - -import { Link } from 'gatsby'; - - - -> ๐Ÿ’ก Not self-hosting your router? Get started with [Cloud Router](/graphos/quickstart/cloud/). - -GraphOS Router is a scalable runtime for supergraphs that's fully integrated with GraphOS and based on the Apollo Router Core. - -A self-hosted GraphOS Router or Apollo Router Core enables full management of your supergraph runtime infrastructure and deployments. - -```mermaid -flowchart LR; - clients(Clients); - subgraph "Your infrastructure"; - router(["Router"]); - serviceB[Products
      API]; - serviceC[Reviews
      API]; - router -->|Sub-query| serviceB & serviceC; - end; - clients -.->|Query| router; - class clients secondary; -``` - -The router intelligently distributes inbound queries across your GraphQL-powered microservices, enabling clients to fetch data from multiple sources with a single request. - -> Learn about the [distinction between the router and an API gateway](/technotes/TN0037-api-gateways/). - - -If you have an existing federated graph that currently uses `@apollo/gateway`, you can move to the router without changing any other part of your graph. - -

      - - -

      - -> **This documentation helps you run a _self-hosted_ instance of a router.** If you [create a cloud supergraph](/graphos/quickstart/cloud/) with Apollo GraphOS, Apollo provisions and hosts a GraphOS Router for you. -> -> Cloud supergraphs are recommended for organizations that don't need to host their router in their own infrastructure. - - -## Features - -- Full support for [Apollo Federation](/federation/) and supergraph management via [GraphOS](/graphos/) -- Extensive declarative [configuration options](./configuration/overview) (header propagation, CORS settings, OpenTelemetry support, and more) -- Support for [scripting](./customizations/rhai/) via the Rhai scripting language -- Advanced [GraphOS Enterprise features](./enterprise-features), including: - - Real-time data via [GraphQL subscriptions](./executing-operations/subscription-support/) - - [JWT authentication](./configuration/authn-jwt) - - [Distributed caching](./configuration/distributed-caching/) for multi-router fleets - - Customization in any language via [external coprocessing](./customizations/coprocessor/) - - [Operation limits](./configuration/operation-limits/) diff --git a/docs/source/privacy.mdx b/docs/source/privacy.mdx deleted file mode 100644 index 5d675f8779..0000000000 --- a/docs/source/privacy.mdx +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: Privacy and Data Collection -subtitle: Learn what data the router collects and how to opt out -description: Learn what data the Apollo GraphOS Router and Apollo Router Core collect and how to opt out. By default, the router collects anonymous usage data to help improve the product. ---- - -By default, the GraphOS Router or Apollo Router Core collects anonymous usage data to help us improve the product. - -The router doesn't collect any personally identifiable information such as API keys, graph names, or file paths. - - - -**To opt out of data collection,** set the `APOLLO_TELEMETRY_DISABLED` environment variable to `true` in each environment where you run the router. - - - -For more information on how this data is collected and used, see [Apollo's privacy policy](https://www.apollographql.com/privacy-policy/). - -## Collected data - -Unless you opt out, the router reports the following data: - -- The execution command that was run _(excluding any identifiable arguments such as file-system paths or profile names)_ -- The version of `router` that was executed -- The configuration properties which have been referenced, but limited to types which could not contain personally identifiable information (e.g., certain scalar types; a property which is set to `true` not the value if it is a `string`) -- A unique, anonymized **machine identifier**, which is the same for every command run on the same machine -- A unique, anonymized **session identifier**, which is different for every command -- The SHA-256 hash of the directory that `router` was executed from -- The SHA-256 hash of the contents of the supergraph schema -- The operating system `router` was executed on -- The CI system `router` was executed on, if any diff --git a/docs/source/enterprise-features.mdx b/docs/source/reference/graphos-features.mdx similarity index 67% rename from docs/source/enterprise-features.mdx rename to docs/source/reference/graphos-features.mdx index a6a1b53352..129e790afa 100644 --- a/docs/source/enterprise-features.mdx +++ b/docs/source/reference/graphos-features.mdx @@ -1,43 +1,37 @@ --- -title: GraphOS Router Enterprise Features -subtitle: Use expanded features of GraphOS Router enabled by an Enterprise plan -description: Unlock Enterprise features for the GraphOS Router by connecting it to Apollo GraphOS. Enable offline licenses for extended disconnections. +title: GraphOS Router Features +subtitle: Use router features enabled by GraphOS and the Enterprise plan +description: Unlock Enterprise features for the GraphOS Router by connecting it to Apollo GraphOS. +redirectFrom: + - /router/enterprise-features --- -GraphOS organizations with the Enterprise plan can [connect a self-hosted router to GraphOS](/graphos/quickstart/self-hosted#6-connect-the-router-to-graphos) for an expanded feature set. +A router connected to GraphOS, whether cloud-hosted or self-hosted, is called a **GraphOS Router**. It has access to specific GraphOS features depending on the connected GraphOS organization's plan. Refer to the [pricing page](https://www.apollographql.com/pricing#graphos-router) to compare GraphOS Router features across plan types. -A router connected to GraphOS, whether cloud- or self-hosted, is called a **GraphOS Router**. It has access to specific GraphOS features depending on the connected GraphOS organization's plan. Refer to the [pricing page](https://www.apollographql.com/pricing#graphos-router) to compare GraphOS Router features across plan types. +## GraphOS Router features - - -Try the Enterprise features of GraphOS Router for free with an [Enterprise trial](/graphos/org/plans/#enterprise-trials). - - + -## List of features +For details on these features, see [this blog post](https://blog.apollographql.com/apollo-router-v1-12-improved-router-security-performance-and-extensibility) in addition to the documentation links above. - +## Enterprise plan features -Articles about Enterprise features are marked with a **โ–** icon in the left navigation. +Try the Enterprise features of GraphOS Router with a free [GraphOS trial](https://www.apollographql.com/pricing). -For details on these features, see [this blog post](https://blog.apollographql.com/apollo-router-v1-12-improved-router-security-performance-and-extensibility) in addition to the documentation links above. - -## Enabling Enterprise features - -To enable support for GraphOS Router Enterprise features: +To enable support for Enterprise features in GraphOS Router: - Your organization must have a [GraphOS Enterprise plan](https://www.apollographql.com/pricing/). -- You must run GraphOS Router v1.12. [Download the latest version.](./quickstart#download-options) +- You must run GraphOS Router v1.12 or later. [Download the latest version.](/graphos/reference/router/self-hosted-install#1-download-and-extract-the-router-binary) - Certain Enterprise features might require a later router version. See a particular feature's documentation for details. - Your router instances must connect to GraphOS with a **graph API key** and **graph ref** associated with your organization. - - You connect your router to GraphOS by setting [these environment variables](./configuration/overview/#environment-variables) when starting the router. + - You connect your router to GraphOS by setting [these environment variables](/graphos/reference/router/configuration#environment-variables) when starting the router. - If your router _already_ connects to your GraphOS Enterprise organization, no further action is required. -After enabling support, you can begin using all Enterprise features. Consult [the documentation for each feature](#list-of-features) to learn more. +After enabling support, you can begin using all [Enterprise features](#graphos-router-features). ### The Enterprise license @@ -54,9 +48,9 @@ flowchart LR; router--"Fetches supergraph schema
      and license"-->uplink; ``` -A router instance retains its license for the duration of its execution. If you terminate a router instance and then later start a new instance on the same machine, it must fetch a new license. +A router instance retains its license for the duration of its execution. If you stop a router instance and then later start a new instance on the same machine, it must fetch a new license. -Licenses are served via [Apollo Uplink](/federation/managed-federation/uplink/), the same multi-cloud endpoint that your router uses to fetch its supergraph schema from GraphOS. Because of this, licenses introduce no additional network dependencies, meaning your router's uptime remains unaffected. To learn more about multi-cloud Uplink, read the [Apollo blog post](https://www.apollographql.com/blog/announcement/backend/introducing-multi-cloud-support-for-apollo-uplink). +Licenses are served via [Apollo Uplink](/graphos/routing/uplink), the same multi-cloud endpoint that your router uses to fetch its supergraph schema from GraphOS. Because of this, licenses introduce no additional network dependencies, meaning your router's uptime remains unaffected. To learn more about multi-cloud Uplink, read the [Apollo blog post](https://www.apollographql.com/blog/announcement/backend/introducing-multi-cloud-support-for-apollo-uplink). A router instance's license is valid for the duration of your organization's current subscription billing period (plus a [grace period](#grace-period-for-expired-plans)), even if the router temporarily becomes disconnected from GraphOS. @@ -74,7 +68,7 @@ Offline Enterprise license support is available on an as-needed basis. Send a re Running your GraphOS Router fleet while fully connected to GraphOS is the best choice for most Apollo users. However, some scenarios can prevent your routers from connecting to GraphOS for an extended period, ranging from disasters that break connectivity to isolated sites operating with air-gapped networks. If you need to restart or rapidly scale your entire router fleet, but you're unable to communicate with Apollo Uplink, new router instances won't be able to serve traffic. -To support long-term disconnection scenarios, GraphOS supports **offline Enterprise licenses** for the GraphOS Router. An offline license enables routers to start and serve traffic without a persistent connection to GraphOS. The functionality available with an offline license is much like being fully connected to GraphOS, including managed federation for supergraph CI (operation checks, schema linting, contracts, etc.). +To support long-term disconnection scenarios, GraphOS supports **offline Enterprise licenses** for the GraphOS Router. An offline license enables routers to start and serve traffic without a persistent connection to GraphOS. The functionality available with an offline license is much like being fully connected to GraphOS, including the GraphOS [schema delivery pipeline](/graphos/platform/schema-management#schema-delivery) for supergraph CI (schema checks, linting, contracts, etc.). An offline license can be retrieved from GraphOS with the [`rover license fetch`](/rover/commands/license) command. @@ -82,7 +76,7 @@ With an offline license, a router can either be fully disconnected from GraphOS -A router using an offline license requires [the use of local manifests](./configuration/persisted-queries/#experimental_local_manifests) when using [safelisting with persisted queries](./configuration/persisted-queries), otherwise it will not work as designed when the router is disconnected from Uplink. +A router using an offline license requires [the use of local manifests](/graphos/routing/security/persisted-queries#experimental_local_manifests) when using [safelisting with persisted queries](/graphos/routing/security/persisted-queries), otherwise it will not work as designed when the router is disconnected from Uplink. @@ -100,9 +94,9 @@ Follow these steps to configure an GraphOS Router to use an offline Enterprise l 1. Provide the offline license to your router on startup. The router accepts an offline license in a few ways: - 1. [`--license `](./configuration/overview/#--license) CLI option, with an argument containing an absolute or relative path to an offline license file - 1. [`APOLLO_ROUTER_LICENSE_PATH`](./configuration/overview/#--license) environment variable, containing an absolute or relative path to an offline license file - 1. [`APOLLO_ROUTER_LICENSE`](./configuration/overview/#--license) environment variable, containing the stringified contents of an offline license file + 1. [`--license `](/graphos/reference/router/configuration#--license) CLI option, with an argument containing an absolute or relative path to an offline license file + 1. [`APOLLO_ROUTER_LICENSE_PATH`](/graphos/reference/router/configuration#--license) environment variable, containing an absolute or relative path to an offline license file + 1. [`APOLLO_ROUTER_LICENSE`](/graphos/reference/router/configuration#--license) environment variable, containing the stringified contents of an offline license file @@ -113,11 +107,11 @@ Follow these steps to configure an GraphOS Router to use an offline Enterprise l 1. Configure the router to use a local supergraph schema by setting one of the following: - * [`--s/-supergraph`](./configuration/overview/#-s----supergraph) CLI option, with an argument containing an absolute or relative path to supergraph schema file - * [`APOLLO_SUPERGRAPH_PATH`](./configuration/overview/#-s----supergraph) environment variable, containing an absolute or relative path to supergraph schema file - * [`APOLLO_SUPERGRAPH_URLS`](./configuration/overview/#-s----supergraph) environment variable, containing URLs to supergraph schemas + * [`--s/-supergraph`](/graphos/reference/router/configuration#-s----supergraph) CLI option, with an argument containing an absolute or relative path to supergraph schema file + * [`APOLLO_SUPERGRAPH_PATH`](/graphos/reference/router/configuration#-s----supergraph) environment variable, containing an absolute or relative path to supergraph schema file + * [`APOLLO_SUPERGRAPH_URLS`](/graphos/reference/router/configuration#-s----supergraph) environment variable, containing URLs to supergraph schemas -1. (**Recommended**) Configure the router to report usage metrics to GraphOS in a best-effort basis by setting both the [`APOLLO_KEY`](./configuration/overview/#apollo_key) and [`APOLLO_GRAPH_REF`](./configuration/overview#apollo_graph_ref) environment variables. +1. (**Recommended**) Configure the router to report usage metrics to GraphOS in a best-effort basis by setting both the [`APOLLO_KEY`](/graphos/reference/router/configuration#apollo_key) and [`APOLLO_GRAPH_REF`](/graphos/reference/router/configuration#apollo_graph_ref) environment variables. These metrics are necessary for several important GraphOS features (operations checks, field insights, operation traces, contracts). Sending them best-effort incurs no performance or uptime penalties. @@ -142,7 +136,7 @@ These steps work both for running the router executable directly (`./router`) an } ``` -2. Create a [graph API key](/graphos/api-keys/#graph-api-keys) for your supergraph and assign it the **Contributor** role. +2. Create a [graph API key](/graphos/platform/access-management/api-keys#graph-api-keys) for your supergraph and assign it the **Contributor** role. - We recommend creating a separate graph API key for _each team member_ that will run the router locally. 3. When you start up your local router with your usual command, set the `APOLLO_GRAPH_REF` and `APOLLO_KEY` environment variables for that command: @@ -151,7 +145,7 @@ These steps work both for running the router executable directly (`./router`) an APOLLO_GRAPH_REF="..." APOLLO_KEY="..." ./router --supergraph schema.graphql ``` - - The value of `APOLLO_GRAPH_REF` is the graph ref for the new, license-specific variant you created (e.g., `docs-example-graph@local-licenses`). + - The value of `APOLLO_GRAPH_REF` is the graph ref for the new, license-specific variant you created (for example, `docs-example-graph@local-licenses`). - The value of `APOLLO_KEY` is the graph API key you created. 4. Your router will fetch an Enterprise license while using its locally composed supergraph schema. @@ -166,13 +160,13 @@ These steps work both for running the router executable directly (`./router`) an | `License not found.` | The router connected to GraphOS with credentials that are not associated with a GraphOS Enterprise plan. | | `License has expired.` | Your organization's GraphOS Enterprise subscription has ended. **Your router will stop processing incoming requests at the end of the standard [grace period](#grace-period-for-expired-plans).** | -## Disabling Enterprise features +## Turning off Enterprise features -To disable an Enterprise feature, remove all of its associated configuration keys from your router's [YAML config file](./configuration/overview/#yaml-config-file). +To turn off an Enterprise feature, remove all of its associated configuration keys from your router's [YAML config file](/graphos/reference/router/configuration#yaml-config-file). ## Grace period for expired plans -If your organization terminates its GraphOS Enterprise subscription, your router's Enterprise license is considered expired at the end of your final paid subscription period. GraphOS provides a grace period for expired licenses so that you can disable Enterprise features before they produce breaking errors in your router. +If your organization terminates its GraphOS Enterprise subscription, your router's Enterprise license is considered expired at the end of your final paid subscription period. GraphOS provides a grace period for expired licenses so that you can turn off Enterprise features before they produce breaking errors in your router. If your router has an expired Enterprise license, its behavior degrades according to the following schedule, _if_ any Enterprise features are still enabled: @@ -180,4 +174,4 @@ If your router has an expired Enterprise license, its behavior degrades accordin - **After 14 days,** your router begins a **soft outage**: it continues processing client requests, but it emits logs and metrics that indicate it's experiencing an outage. - **After 28 days,** your router begins a **hard outage**. It no longer processes incoming client requests and continues emitting logs and metrics from the soft outage. -Your router resumes normal functioning whenever you renew your GraphOS Enterprise subscription or disable all [Enterprise features](#list-of-features). +Your router resumes normal functioning whenever you renew your GraphOS Enterprise subscription or turn off all [Enterprise features](#list-of-features). diff --git a/docs/source/migrating-from-gateway.mdx b/docs/source/reference/migration/from-gateway.mdx similarity index 85% rename from docs/source/migrating-from-gateway.mdx rename to docs/source/reference/migration/from-gateway.mdx index 4ae7ae2bed..e1fa6222a3 100644 --- a/docs/source/migrating-from-gateway.mdx +++ b/docs/source/reference/migration/from-gateway.mdx @@ -4,19 +4,13 @@ subtitle: Migrating to the router from @apollo/gateway description: Learn how to migrate a federated graph from @apollo/gateway to the Apollo GraphOS Router or Apollo Router Core without any changes to your subgraphs. --- - - Learn how to migrate a federated supergraph using the `@apollo/gateway` library to the GraphOS Router or Apollo Router Core and gain significant performance improvements while making zero changes to your subgraphs. ## What's different? Whereas `@apollo/gateway` is an npm package, the router is packaged as a _static, standalone binary_. -The router exposes the most common critical features via declarative configuration. You customize the router with a [YAML configuration file](./configuration/overview/#yaml-config-file) that takes effect at startup. Configurations can be modified and take effect without restart if you either start the router with the `--hot-reload` flag or set the `APOLLO_ROUTER_HOT_RELOAD` environment variable to `true`. +The router exposes the most common critical features via declarative configuration. You customize the router with a [YAML configuration file](/router/configuration/overview/#yaml-config-file) that takes effect at startup. Configurations can be modified and take effect without restart if you either start the router with the `--hot-reload` flag or set the `APOLLO_ROUTER_HOT_RELOAD` environment variable to `true`. Although you _can_ download the Apollo Router Core source and use it as a library in a larger project and as the basis for a self-hosted GraphOS Router, you may not need to because the features that were implemented by custom code with `@apollo/gateway` may be standard, supported features of the router. @@ -85,9 +79,9 @@ The [`buildService` function](/apollo-server/using-federation/api/apollo-gateway Common use cases include: * Overriding subgraph URLs at runtime - * In the router, you can use the [`override_subgraph_urls` option](./configuration/overview#subgraph-routing-urls). + * In the router, you can use the [`override_subgraph_urls` option](/router/configuration/overview#subgraph-routing-urls). * Propagating headers to subgraphs via `RemoteGraphQLDataSource` - * In the router, you can use the [`headers` option](./configuration/header-propagation). + * In the router, you can use the [`headers` option](/graphos/routing/header-propagation). ### `logger` @@ -95,7 +89,7 @@ The [`logger` constructor option](/apollo-server/using-federation/api/apollo-gat In the router, logging is JSON-structured in production environments by default, and you can adjust the verbosity. More advanced logging can be enabled through the use of [plugins](#plugins). -For more information, see [Logging in the router](./configuration/logging/). +For more information, see [Logging in the router](/router/configuration/telemetry/exporters/logging/overview). ## `ApolloServer` constructor options @@ -113,13 +107,13 @@ This constructor option is an object that enables you to propagate information a * Authentication information * Header propagation -The router provides [similar functionality](./customizations/rhai-api#requestcontext). +The router provides [similar functionality](/graphos/reference/router/rhai#requestcontext). ### `plugins` This constructor option is an array of built-in or custom `plugins` that extend Apollo Server's functionality. If you provide `plugins` to your `ApolloServer` instance, take note of each plugin's functionality and add it to your migration checklist. -Before you attempt to replicate a plugin's functionality via a router [customization](#supported-customizations), check whether any router [configuration options](./configuration/overview/) provide that same functionality. For example, the router supports options for propagating HTTP headers to subgraphs and enabling OpenTelemetry instrumentation. +Before you attempt to replicate a plugin's functionality via a router [customization](#supported-customizations), check whether any router [configuration options](/router/configuration/overview/) provide that same functionality. For example, the router supports options for propagating HTTP headers to subgraphs and enabling OpenTelemetry instrumentation. If one of your `@apollo/gateway` plugins _does_ require a corresponding router customization, we encourage you to describe your use case in the router repo's [GitHub discussions](https://github.com/apollographql/router/discussions/). It might represent core functionality that the router _should_ provide out of the box, and we can help discuss the design. @@ -129,21 +123,21 @@ For less common use cases, we also want to help build an ecosystem of shared cus The router supports two types of customizations that hook into the request-handling pipeline: -* [Rhai scripts](./customizations/rhai/) +* [Rhai scripts](/graphos/routing/customization/rhai/) * Rhai is a scripting language designed for use with Rust applications. -* [External coprocessing](./customizations/coprocessor/) +* [External coprocessing](/router/customizations/coprocessor/) Examples for each are provided in their respective documentation, and in the [Router repo](https://github.com/apollographql/router/tree/main/examples). ## Kubernetes deployment -For migrating to the router deployed on Kubernetes, see some tips for [configuring your router deployment](./containerization/kubernetes/#configure-for-migration-from-gateway). +For migrating to the router deployed on Kubernetes, see some tips for [configuring your router deployment](/router/containerization/kubernetes/#configure-for-migration-from-gateway). ## Responses and errors Apollo Gateway runs its core GraphQL server using Apollo Server and a user configured HTTP server. GraphOS Router is built as an all-in-one product with the GraphQL and HTTP server bundled together. With this change there may be some slight difference to the logic of HTTP status codes or GraphQL error extension codes. -Refer the full list of [router error codes](./errors) for any changes to your gateway implementation. If you need to customize the responses, refer to [router customizations](./customizations/overview). +Refer the full list of [router error codes](/router/errors) for any changes to your gateway implementation. If you need to customize the responses, refer to [router customizations](/router/customizations/overview). ## Reporting migration issues diff --git a/docs/source/migrating-from-version-0.x.mdx b/docs/source/reference/migration/from-router-version-0.x.mdx similarity index 88% rename from docs/source/migrating-from-version-0.x.mdx rename to docs/source/reference/migration/from-router-version-0.x.mdx index 11589821d6..af1dcec1df 100644 --- a/docs/source/migrating-from-version-0.x.mdx +++ b/docs/source/reference/migration/from-router-version-0.x.mdx @@ -15,7 +15,7 @@ Our pre-1.0 versions of the router had highly iterative development lifecycles a - Rhai scripting capabilities - the exposed API -In most cases, things have been moved around in order to strike the right balanace of user experience and functionality without over-exposing things that we'd like to still design further. +In most cases, things have been moved around in order to strike the right balance of user experience and functionality without over-exposing things that we'd like to still design further. The changes you'll need to make depend on which version you were coming from. The key versions before 1.0 included: @@ -46,7 +46,7 @@ In addition, the following command line flags have changed: Removed --apollo-graph-key and --apollo-graph-ref -Unlike `@apollo/gateway`, the Apollo Router Core is packaged as a _static, standalone binary_. To customize its behavior, you pass it a [YAML configuration file](./configuration/overview/#yaml-config-file) at startup. If you start the router with the `--hot-reload` flag (or set the `APOLLO_ROUTER_HOT_RELOAD` environment variable to `true`), you can even modify that configuration without a restart. +Unlike `@apollo/gateway`, the Apollo Router Core is packaged as a _static, standalone binary_. To customize its behavior, you pass it a [YAML configuration file](/router/configuration/overview/#yaml-config-file) at startup. If you start the router with the `--hot-reload` flag (or set the `APOLLO_ROUTER_HOT_RELOAD` environment variable to `true`), you can even modify that configuration without a restart. You _can_ download the router source and use it as a library in a larger project. However, our goal is to remove the need to write custom code in your graph router (which is always necessary with `@apollo/gateway`). Instead, the router exposes the most common critical features via declarative configuration. @@ -115,9 +115,9 @@ The [`buildService` function](/apollo-server/using-federation/api/apollo-gateway Common use cases include: * Overriding subgraph URLs at runtime - * In the router, you can use the [`override_subgraph_urls` option](./configuration/overview#subgraph-routing-urls). + * In the router, you can use the [`override_subgraph_urls` option](/router/configuration/overview#subgraph-routing-urls). * Propagating headers to subgraphs via `RemoteGraphQLDataSource` - * In the router, you can use the [`headers` option](./configuration/header-propagation). + * In the router, you can use the [`headers` option](/graphos/routing/header-propagation). ### `logger` @@ -125,7 +125,7 @@ The [`logger` constructor option](/apollo-server/using-federation/api/apollo-gat In the router, logging is JSON-structured in production environments by default, and you can adjust the verbosity. More advanced logging can be enabled through the use of [plugins](#plugins). -For more information, see [Logging in the router](./configuration/logging/). +For more information, see [Logging in the router](/router/configuration/telemetry/exporters/logging/overview). ## `ApolloServer` constructor options @@ -143,13 +143,13 @@ This constructor option is an object that enables you to propagate information a * Authentication information * Header propagation -The router provides [similar functionality](./customizations/rhai-api/#requestcontext). +The router provides [similar functionality](/graphos/reference/router/rhai/#requestcontext). ### `plugins` This constructor option is an array of built-in or custom `plugins` that extend Apollo Server's functionality. If you provide `plugins` to your `ApolloServer` instance, take note of each plugin's functionality and add it to your migration checklist. -Before you attempt to replicate a plugin's functionality via a router [customization](#supported-customizations), check whether any router [configuration options](./configuration/overview/) provide that same functionality. For example, the router supports options for propagating HTTP headers to subgraphs and enabling OpenTelemetry instrumentation. +Before you attempt to replicate a plugin's functionality via a router [customization](#supported-customizations), check whether any router [configuration options](/router/configuration/overview/) provide that same functionality. For example, the router supports options for propagating HTTP headers to subgraphs and enabling OpenTelemetry instrumentation. > If one of your `@apollo/gateway` plugins _does_ require a corresponding router customization, we encourage you to describe your use case in the router repo's [GitHub discussions](https://github.com/apollographql/router/discussions/). It might represent core functionality that the router _should_ provide out of the box, and we can help discuss the design. > @@ -159,10 +159,10 @@ Before you attempt to replicate a plugin's functionality via a router [customiza The router currently supports two types of customizations that hook into the request-handling pipeline: -* [Rhai scripts](./customizations/rhai/) +* [Rhai scripts](/graphos/routing/customization/rhai/) * Rhai is a scripting language designed for use with Rust applications. -* [External coprocessing](./customizations/coprocessor/). - * Requires a [GraphOS Router with an Enterprise plan](./enterprise-features). +* [External coprocessing](/router/customizations/coprocessor/). + * Requires a [GraphOS Router with an Enterprise plan](/router/enterprise-features). Examples for each are provided in their respective documentation, and in the [Router repo](https://github.com/apollographql/router/tree/main/examples). diff --git a/docs/source/configuration/overview.mdx b/docs/source/reference/router/configuration.mdx similarity index 85% rename from docs/source/configuration/overview.mdx rename to docs/source/reference/router/configuration.mdx index cd3dcf155c..3c89326a73 100644 --- a/docs/source/configuration/overview.mdx +++ b/docs/source/reference/router/configuration.mdx @@ -4,8 +4,6 @@ subtitle: Configure a router via environment variables, command-line options, an description: Learn how to configure the Apollo GraphOS Router or Apollo Router Core with environment variables, command-line options and commands, and YAML configuration files. --- -import RedisTLS from '../../shared/redis-tls.mdx' - Learn how to customize the behavior of your GraphOS Router or Apollo Router Core with environment variables, command-line commands and options, and YAML file configuration. ## Environment variables @@ -76,7 +74,7 @@ A path to a file containing the [graph API key](/graphos/api-keys/#graph-api-key ## Command-line options -After [installing the Apollo Router Core](../quickstart/) in your current working directory, you can run the router with the following example command: +After [installing the Apollo Router Core](/router/quickstart) in your current working directory, you can run the router with the following example command: ```bash ./router --config router.yaml --supergraph supergraph-schema.graphql @@ -104,13 +102,13 @@ This reference lists and describes the options supported by the `router` binary. -The [supergraph schema](/federation/federated-types/overview/#supergraph-schema) of a router. Specified by absolute or relative path (`-s` / `--supergraph `, or `APOLLO_ROUTER_SUPERGRAPH_PATH`), or a comma-separated list of URLs (`APOLLO_ROUTER_SUPERGRAPH_URLS`). +The [supergraph schema](/federation/federated-types/overview#supergraph-schema) of a router. Specified by absolute or relative path (`-s` / `--supergraph `, or `APOLLO_ROUTER_SUPERGRAPH_PATH`), or a comma-separated list of URLs (`APOLLO_ROUTER_SUPERGRAPH_URLS`). > 💡 Avoid embedding tokens in `APOLLO_ROUTER_SUPERGRAPH_URLS` because the URLs may appear in log messages. Setting this option disables polling from Apollo Uplink to fetch the latest supergraph schema. -To learn how to compose your supergraph schema with the Rover CLI, see the [Federation quickstart](/federation/quickstart/local-composition/). +To learn how to compose your supergraph schema with the Rover CLI, see the [Federation quickstart](/federation/quickstart). **Required** if you are _not_ using managed federation. If you _are_ using managed federation, you may need to set this option when following [advanced deployment workflows](/federation/managed-federation/deployment/#advanced-deployment-workflows). @@ -212,9 +210,9 @@ An offline GraphOS Enterprise license. Enables Enterprise router features when d An offline license is specified either as an absolute or relative path to a license file (`--license ` or `APOLLO_ROUTER_LICENSE_PATH`), or as the stringified contents of a license (`APOLLO_ROUTER_LICENSE`). -When not set, the router retrieves an Enterprise license [from GraphOS via Apollo Uplink](../enterprise-features/#the-enterprise-license). +When not set, the router retrieves an Enterprise license [from GraphOS via Apollo Uplink](/router/enterprise-features/#the-enterprise-license). -For information about fetching an offline license and configuring the router, see [Offline Enterprise license](../enterprise-features/#offline-enterprise-license). +For information about fetching an offline license and configuring the router, see [Offline Enterprise license](/router/enterprise-features/#offline-enterprise-license). @@ -501,9 +499,9 @@ supergraph: ### Debugging -- To configure logging, see [Logging in the router](./telemetry/exporters/logging/overview). +- To configure logging, see [Logging in the router](/router/configuration/telemetry/exporters/logging/overview). -- To configure the inclusion of subgraph errors, see [Subgraph error inclusion](./subgraph-error-inclusion). +- To configure the inclusion of subgraph errors, see [Subgraph error inclusion](/router/configuration/subgraph-error-inclusion). ### Landing pages @@ -563,7 +561,7 @@ In this example, the `organizations` subgraph URL is overridden to point to `htt Any subgraphs that are _omitted_ from `override_subgraph_url` continue to use the routing URL specified in the supergraph schema. -If you need to override the subgraph URL at runtime on a per-request basis, you can use [request customizations](../customizations/overview/#request-path) in the `SubgraphService` layer. +If you need to override the subgraph URL at runtime on a per-request basis, you can use [request customizations](/router/customizations/overview/#request-path) in the `SubgraphService` layer. ### Caching @@ -573,11 +571,38 @@ By default, the router stores the following data in its in-memory cache to impro - Automatic persisted queries (APQ) - Introspection responses -You can configure certain caching behaviors for generated query plans and APQ (but not introspection responses). For details, see [In-Memory Caching in the router](./in-memory-caching/). +You can configure certain caching behaviors for generated query plans and APQ (but not introspection responses). For details, see [In-Memory Caching in the router](/router/configuration/in-memory-caching/). **If you have a GraphOS Enterprise plan:** -- You can configure a Redis-backed _distributed_ cache that enables multiple router instances to share cached values. For details, see [Distributed caching in the GraphOS Router](./distributed-caching/). -- You can configure a Redis-backed _entity_ cache that enables a client query to retrieve cached entity data split between subgraph reponses. For details, see [Subgraph entity caching in the GraphOS Router](./entity-caching/). +- You can configure a Redis-backed _distributed_ cache that enables multiple router instances to share cached values. For details, see [Distributed caching in the GraphOS Router](/router/configuration/distributed-caching/). +- You can configure a Redis-backed _entity_ cache that enables a client query to retrieve cached entity data split between subgraph reponses. For details, see [Subgraph entity caching in the GraphOS Router](/router/configuration/entity-caching/). + + + +### Native query planner + + + +Starting with v1.49.0, the router can run a Rust-native query planner. This native query planner can be run by itself to plan all queries, replacing the legacy JavaScript implementation. + + + +Starting with v1.57.0, to run the most performant and resource-efficient native query planner and to disable the V8 JavaScript runtime in the router, set the following options in your `router.yaml`: + +```yaml title="router.yaml" +experimental_query_planner_mode: new +``` + +You can also improve throughput by reducing the size of queries sent to subgraphs with the following option: + +```yaml title="router.yaml" +supergraph: + generate_query_fragments: true +``` + + + +Learn more in [Native Query Planner](/router/executing-operations/native-query-planner) docs. @@ -822,60 +847,65 @@ To ensure sufficient data to distinguish between genuinely unused values and tho Thanks to extended reference reporting, operation checks can more accurately flag issues for changes to enum values and input object fields. See the comparison table below for differences between standard operation checks based on legacy reference reporting and enhanced checks based on extended reference reporting. - - - - - - - + + + + + + + + + - - - - - + + + + + - - - + + - - - + + + - - - - - + + + + + - - - + + + + +
      -Standard Check Behavior
      -(Legacy reference reporting) -
      -Enhanced Check Behavior
      -(Extended reference reporting) -
      +
      + Standard Check Behavior
      + (Legacy reference reporting) +
      + Enhanced Check Behavior
      + (Extended reference reporting) +
      ##### Enum value removal -Removing any enum values is considered a breaking change if any operations use the enum.Removing enum values is only a breaking change if historical operations use the specific enum value(s) that were removed.
      + Removing any enum values is considered a breaking change if any operations use the enum.Removing enum values is only a breaking change if historical operations use the specific enum value(s) that were removed.
      ##### Default argument changes for input object fields -Changing or removing a default argument is generally considered a breaking change, but changing or removing default values for input object fields isn't. + + Changing or removing a default argument is generally considered a breaking change, but changing or removing default values for input object fields isn't. + + Changing or removing default values for input object fields is considered a breaking change. +You can [configure checks to ignore default values changes](/graphos/platform/schema-management/checks#ignored-conditions-settings). -Changing or removing default values for input object fields is considered a breaking change. -You can [configure checks to ignore default values changes](/graphos/delivery/schema-checks/#ignored-conditions-settings). - -
      +
      ##### Nullable input object field removal -Removing a nullable input object field is always considered a breaking change.Removing a nullable input object field is only considered a breaking change if the nullable field is present in historical operations. If the nullable field is always omitted in historical operations, its removal isn't considered a breaking change.
      + Removing a nullable input object field is always considered a breaking change.Removing a nullable input object field is only considered a breaking change if the nullable field is present in historical operations. If the nullable field is always omitted in historical operations, its removal isn't considered a breaking change.
      ##### Changing nullable input object fields to non-nullable -Changing a nullable input object field to non-nullable is considered a breaking change.Changing a nullable input object field to non-nullable is only considered a breaking change if the field had a null value in historical operations. If the field was always a non-null value in historical operations, changing it to non-nullable isn't considered a breaking change.
      Changing a nullable input object field to non-nullable is considered a breaking change.Changing a nullable input object field to non-nullable is only considered a breaking change if the field had a null value in historical operations. If the field was always a non-null value in historical operations, changing it to non-nullable isn't considered a breaking change.
      + You won't see an immediate change in checks behavior when you first turn on extended reference reporting. @@ -883,77 +913,63 @@ You won't see an immediate change in checks behavior when you first turn on exte - - -### Enhanced tracing in Studio via OpenTelemetry - - - - - -Beginning in v1.49.0, the router supports sending traces to Studio via the OpenTelemetry Protocol (OTLP). -Support for OTLP traces has historically only been available for third-party APM tools. With this option, -Studio can now provide a much more granular and detailed view of router internals than the previous Apollo tracing protocol. - -To learn more, see [Enhanced tracing in Studio via OpenTelemetry](./telemetry/apollo-telemetry#enhanced-tracing-in-studio-via-opentelemetry). - ### Safelisting with persisted queries You can enhance your graph's security with GraphOS Router by maintaining a persisted query list (PQL), an operation safelist made by your first-party apps. As opposed to automatic persisted queries (APQ) where operations are automatically cached, operations must be preregistered to the PQL. Once configured, the router checks incoming requests against the PQL. -See [Safelisting with persisted queries](./persisted-queries) for more information. +See [Safelisting with persisted queries](/router/configuration/persisted-queries) for more information. ### HTTP header rules -See [Sending HTTP headers to subgraphs](./header-propagation/). +See [Sending HTTP headers to subgraphs](/graphos/routing/header-propagation/). ### Traffic shaping -To configure the shape of traffic between clients, routers, and subgraphs, see [Traffic shaping in the router](./traffic-shaping). +To configure the shape of traffic between clients, routers, and subgraphs, see [Traffic shaping in the router](/router/configuration/traffic-shaping). ### Cross-Origin Resource Sharing (CORS) -See [Configuring CORS in the router](./cors). +See [Configuring CORS in the router](/router/configuration/cors). ### Defer support -See [router support for `@defer`](../executing-operations/defer-support/#disabling-defer). +See [router support for `@defer`](/router/executing-operations/defer-support/#disabling-defer). ### Query batching support -See [GraphOS Router's support for query batching](../executing-operations/query-batching). +See [GraphOS Router's support for query batching](/router/executing-operations/query-batching). ### Subscription support -See [GraphQL subscriptions in the GraphOS Router](../executing-operations/subscription-support/#router-setup). +See [GraphQL subscriptions in the GraphOS Router](/router/executing-operations/subscription-support/#router-setup). ### Authorization support -- To configure authorization directives, see [Authorization directives](./authorization/#authorization-directives). +- To configure authorization directives, see [Authorization directives](/router/configuration/authorization/#authorization-directives). -- To configure the authorization plugin, see [Configuration options](./authorization/#configuration-options). +- To configure the authorization plugin, see [Configuration options](/router/configuration/authorization/#configuration-options). ### JWT authentication -To enable and configure JWT authentication, see [JWT authentication in the GraphOS Router](./authn-jwt). +To enable and configure JWT authentication, see [JWT authentication in the GraphOS Router](/router/configuration/authn-jwt). ### Cross-site request forgery (CSRF) prevention -To configure CSRF prevention, see [CSRF prevention in the router](./csrf). +To configure CSRF prevention, see [CSRF prevention in the router](/router/configuration/csrf). ### Subgraph authentication -To configure subgraph authentication with AWS SigV4, see a [configuration example](./authn-subgraph/#configuration-example). +To configure subgraph authentication with AWS SigV4, see a [configuration example](/router/configuration/authn-subgraph/#configuration-example). ### External coprocessing -See [External coprocessing in the GraphOS Router](../customizations/coprocessor/). +See [External coprocessing in the GraphOS Router](/router/customizations/coprocessor/). ### Telemetry and monitoring The router supports standard and custom instrumentation to collect telemetry data from its request and response processing pipeline to produce logs, metrics and traces to export. -See the [router telemetry overview](./telemetry/overview). +See the [router telemetry overview](/router/configuration/telemetry/overview). ### TLS @@ -1067,7 +1083,22 @@ tls: #### Redis TLS configuration - +For Redis TLS connections, you can set up a client certificate or override the root certificate authority by configuring `tls` in your router's [YAML config file](https://www.apollographql.com/docs/router/overview/#yaml-config-file). For example: + +```yaml +apq: + router: + cache: + redis: + urls: [ "rediss://redis.example.com:6379" ] + #highlight-start + tls: + certificate_authorities: ${file./path/to/ca.crt} + client_authentication: + certificate_chain: ${file./path/to/certificate_chain.pem} + key: ${file./path/to/key.pem} + #highlight-end +``` ### Request limits @@ -1075,7 +1106,7 @@ The GraphOS Router supports enforcing three types of request limits for enhanced - Network-based limits - Lexical, parser-based limits -- Semantic, operation-based limits (this is an [Enterprise feature](../enterprise-features/)) +- Semantic, operation-based limits (this is an [Enterprise feature](/router/enterprise-features/)) The router rejects any request that violates at least one of these limits. @@ -1097,7 +1128,7 @@ limits: #### Operation-based limits (Enterprise only) -See [this article](./operation-limits/). +See [this article](/router/configuration/operation-limits/). #### Network-based limits @@ -1151,7 +1182,7 @@ Note that the router calculates the recursion depth for each operation and fragm ### Demand control -See [Demand Control](../executing-operations/demand-control) to learn how to analyze the cost of operations and to reject requests with operations that exceed customizable cost limits. +See [Demand Control](/router/executing-operations/demand-control) to learn how to analyze the cost of operations and to reject requests with operations that exceed customizable cost limits. ### Early cancel @@ -1173,7 +1204,7 @@ supergraph: ### Plugins -You can customize the router's behavior with [plugins](../customizations/overview). Each plugin can have its own section in the configuration file with arbitrary values: +You can customize the router's behavior with [plugins](/router/customizations/overview). Each plugin can have its own section in the configuration file with arbitrary values: ```yaml {4,8} title="example-plugin-router.yaml" plugins: @@ -1221,6 +1252,12 @@ supergraph: generate_query_fragments: true ``` + + +In the future, the `generate_query_fragments` option will be the only option for handling fragments. + + + ### Reusing configuration You can reuse parts of your configuration file in multiple places using standard YAML aliasing syntax: diff --git a/docs/source/errors.mdx b/docs/source/reference/router/errors.mdx similarity index 87% rename from docs/source/errors.mdx rename to docs/source/reference/router/errors.mdx index aa4bd41c88..6878ea20e0 100644 --- a/docs/source/errors.mdx +++ b/docs/source/reference/router/errors.mdx @@ -24,7 +24,6 @@ Requests may receive this response in two cases: -A request used an unallowed HTTP method. @@ -45,7 +44,7 @@ A request's HTTP `Accept` header didn't contain any of the router's supported mi -Request traffic exceeded configured rate limits. See [client side traffic shaping](./configuration/traffic-shaping/#client-side-traffic-shaping). +Request traffic exceeded configured rate limits. See [client side traffic shaping](/router/configuration/traffic-shaping/#client-side-traffic-shaping). @@ -61,14 +60,14 @@ The router encountered an unexpected issue. [Report](https://github.com/apollogr -The request was not able to complete within a configured amount of time. See [client side traffic shaping timeouts](./configuration/traffic-shaping/#timeouts). +The request was not able to complete within a configured amount of time. See [client side traffic shaping timeouts](/router/configuration/traffic-shaping/#timeouts). -You can create Rhai scripts that throw custom status codes. See [Terminating client requests](./customizations/rhai-api#terminating-client-requests) to learn more. +You can create Rhai scripts that throw custom status codes. See [Terminating client requests](/graphos/reference/router/rhai#terminating-client-requests) to learn more. @@ -76,7 +75,7 @@ You can create Rhai scripts that throw custom status codes. See [Terminating cli ### Demand control -Errors returned by the router when [demand control](./executing-operations/demand-control) is enabled. +Errors returned by the router when [demand control](/router/executing-operations/demand-control) is enabled. @@ -99,12 +98,10 @@ The query could not be parsed. The response from a subgraph did not match the GraphQL schema. - A subgraph returned a field with a different type that mandated by the GraphQL schema. - diff --git a/docs/source/federation-version-support.mdx b/docs/source/reference/router/federation-version-support.mdx similarity index 100% rename from docs/source/federation-version-support.mdx rename to docs/source/reference/router/federation-version-support.mdx diff --git a/docs/source/customizations/rhai-api.mdx b/docs/source/reference/router/rhai.mdx similarity index 97% rename from docs/source/customizations/rhai-api.mdx rename to docs/source/reference/router/rhai.mdx index a881d3f0ff..23b11026ec 100644 --- a/docs/source/customizations/rhai-api.mdx +++ b/docs/source/reference/router/rhai.mdx @@ -4,11 +4,11 @@ subtitle: APIs for router customizations description: This reference documents the symbols and behaviors that are specific to Rhai customizations for the Apollo GraphOS Router and Apollo Router Core. Includes entry point hooks, logging, and more. --- -This reference documents the symbols and behaviors that are specific to [Rhai customizations](./rhai/) for the GraphOS Router and Apollo Router Core. +This reference documents the symbols and behaviors that are specific to [Rhai customizations](/graphos/routing/customization/rhai/) for the GraphOS Router and Apollo Router Core. ## Entry point hooks -Your Rhai script's [main file](./rhai/#the-main-file) hooks into the individual services of the router's [request-handling lifecycle](./rhai/#router-request-lifecycle). To do so, it defines whichever combination of the following entry point hooks it requires: +Your Rhai script's [main file](/graphos/routing/customization/rhai/#the-main-file) hooks into the individual services of the router's [request-handling lifecycle](/graphos/routing/customization/rhai/#router-request-lifecycle). To do so, it defines whichever combination of the following entry point hooks it requires: ```rhai fn router_service(service) {} @@ -17,7 +17,7 @@ fn execution_service(service) {} fn subgraph_service(service, subgraph) {} ``` -Within each hook, you define custom logic to interact with the current active request and/or response as needed. This most commonly involves using methods of the provided `service` object to [register service callbacks](./rhai/#service-callbacks), like so: +Within each hook, you define custom logic to interact with the current active request and/or response as needed. This most commonly involves using methods of the provided `service` object to [register service callbacks](/graphos/routing/customization/rhai/#service-callbacks), like so: ```rhai title="main.rhai" fn supergraph_service(service) { @@ -117,7 +117,7 @@ fn supergraph_service(service) { } ``` -Rhai throws at the `map_request` layer behave the same as `ControlFlow::Break`, which is explained in the [external extensibility section](./coprocessor/#terminating-a-client-request). +Rhai throws at the `map_request` layer behave the same as `ControlFlow::Break`, which is explained in the [external extensibility section](/router/customizations/coprocessor/#terminating-a-client-request). If the supplied status code is not a valid HTTP status code, then a `500` response code will result. diff --git a/docs/source/quickstart.mdx b/docs/source/reference/router/self-hosted-install.mdx similarity index 97% rename from docs/source/quickstart.mdx rename to docs/source/reference/router/self-hosted-install.mdx index 9e6649d1a7..c6711568ba 100644 --- a/docs/source/quickstart.mdx +++ b/docs/source/reference/router/self-hosted-install.mdx @@ -4,7 +4,7 @@ subtitle: Run the router with GraphOS and Apollo-hosted subgraphs description: This quickstart tutorial walks you through installing the Apollo GraphOS Router or Apollo Router Core and running it with GraphOS and some example Apollo-hosted subgraphs. --- -import ElasticNotice from "../shared/elastic-notice.mdx"; +import ElasticNotice from "../../../shared/elastic-notice.mdx"; Hello! This tutorial walks you through installing the router (GraphOS Router or Apollo Router Core) and running it in with GraphOS and some example Apollo-hosted subgraphs. @@ -259,7 +259,7 @@ That's it! Running the router with the `--dev` flag enables a development mode t **Do not use the `--dev` flag in a non-development environment.** It relaxes certain default configuration options to provide an improved local development experience (e.g., it exposes subgraph error messages to clients). -[Learn more about dev mode defaults.](./configuration/overview#dev-mode-defaults) +[Learn more about dev mode defaults.](/router/configuration/overview#dev-mode-defaults) @@ -270,5 +270,5 @@ Visit `http://127.0.0.1:4000` to open Apollo Sandbox, inspect your entire superg Now that you know how to run the router with a supergraph schema, you can: - Set up [managed federation](/federation/managed-federation/overview) -- Learn about [additional configuration options](./configuration/overview) +- Learn about [additional configuration options](/router/configuration/overview) - [Estimate the system resources needed to deploy the router](/technotes/TN0045-router_resource_estimator/). diff --git a/docs/source/configuration/telemetry/instrumentation/conditions.mdx b/docs/source/reference/router/telemetry/instrumentation/conditions.mdx similarity index 89% rename from docs/source/configuration/telemetry/instrumentation/conditions.mdx rename to docs/source/reference/router/telemetry/instrumentation/conditions.mdx index d67c75572e..e98316df27 100644 --- a/docs/source/configuration/telemetry/instrumentation/conditions.mdx +++ b/docs/source/reference/router/telemetry/instrumentation/conditions.mdx @@ -4,7 +4,7 @@ subtitle: Set conditions for when events or instruments are triggered description: Set conditions for when events or instruments are triggered in the Apollo GraphOS Router. --- -You can set conditions for when an [instrument](./instruments) should be mutated or an [event](./events) should be triggered. +You can set conditions for when an [instrument](/router/configuration/telemetry/instrumentation/instruments) should be mutated or an [event](/router/configuration/telemetry/instrumentation/events) should be triggered. ## Condition configuration @@ -35,7 +35,7 @@ telemetry: #### `exists` -The `exists` condition is testing if [selectors](./selectors) is present. +The `exists` condition is testing if [selectors](/router/configuration/telemetry/instrumentation/selectors) is present. For example, the following condition checks the value of `x-req-header` exists: @@ -46,7 +46,7 @@ exists: #### `eq` -The `eq` condition is an equality test between [selectors](./selectors) or values. +The `eq` condition is an equality test between [selectors](/router/configuration/telemetry/instrumentation/selectors) or values. For example, the following condition checks the value of `x-req-header` is equal to `val`: diff --git a/docs/source/configuration/telemetry/instrumentation/events.mdx b/docs/source/reference/router/telemetry/instrumentation/events.mdx similarity index 86% rename from docs/source/configuration/telemetry/instrumentation/events.mdx rename to docs/source/reference/router/telemetry/instrumentation/events.mdx index a4a3418f44..dd06fd6c26 100644 --- a/docs/source/configuration/telemetry/instrumentation/events.mdx +++ b/docs/source/reference/router/telemetry/instrumentation/events.mdx @@ -4,10 +4,10 @@ subtitle: Capture events from the router's request lifecycle description: Capture standard and custom events from the Apollo GraphOS Router's request lifecycle services. --- -import RouterServices from '../../../../shared/router-lifecycle-services.mdx'; -import TelemetryPerformanceNote from '../../../../shared/telemetry-performance.mdx'; +import RouterServices from '../../../../../shared/router-lifecycle-services.mdx'; +import TelemetryPerformanceNote from '../../../../../shared/telemetry-performance.mdx'; -An _event_ is used to signal when something of note happens in the [GraphOS Router's request lifecycle](../../../customizations/overview/#the-request-lifecycle). Events are output to both logs and traces. +An _event_ is used to signal when something of note happens in the [GraphOS Router's request lifecycle](/router/customizations/overview/#the-request-lifecycle). Events are output to both logs and traces. You can configure events for each service in `router.yaml`. Events can be standard or custom, and they can be triggered by configurable conditions. @@ -60,7 +60,7 @@ telemetry: # ... ``` -But you can also enable these standard events based on [conditions](./conditions) (not supported on batched requests). +But you can also enable these standard events based on [conditions](/router/configuration/telemetry/instrumentation/conditions) (not supported on batched requests). For example: ```yaml title="router.yaml" @@ -174,13 +174,13 @@ telemetry: - response_status: Code ``` -For more details, see [Conditions](./conditions). +For more details, see [Conditions](/router/configuration/telemetry/instrumentation/conditions). ### `attributes` Custom events may have attributes attached to them from the router's request lifecycle. These attributes are used to filter and group spans in your APM. -Attributes may be drawn from [standard attributes](./standard-attributes) or [selectors](./selectors). +Attributes may be drawn from [standard attributes](/router/configuration/telemetry/instrumentation/standard-attributes) or [selectors](/router/configuration/telemetry/instrumentation/selectors). The attributes available depend on the service of the request lifecycle. ```yaml title="future.router.yaml" @@ -236,8 +236,8 @@ telemetry: | Option | Values | Default | Description | |--------------------|------------------------------------------------------------------------------|---------|-------------------------------------------------------------| | `` | | | The name of the custom attribute. | -| `attributes` | [standard attributes](./standard-attributes) or [selectors](./selectors) | | The attributes of the custom log event. | -| `condition` | [conditions](./conditions) | | The condition that must be met for the event to be emitted. | +| `attributes` | [standard attributes](/router/configuration/telemetry/instrumentation/standard-attributes) or [selectors](/router/configuration/telemetry/instrumentation/selectors) | | The attributes of the custom log event. | +| `condition` | [conditions](/router/configuration/telemetry/instrumentation/conditions) | | The condition that must be met for the event to be emitted. | | `error` | `trace`\|`info`\|`warn`\|`error`\| `off` | `off` | The level of the error log event. | | `level` | `trace`\|`info`\|`warn`\|`error`\| `off` | `off` | The level of the custom log event. | | `message` | | | The message of the custom log event. | diff --git a/docs/source/configuration/telemetry/instrumentation/instruments.mdx b/docs/source/reference/router/telemetry/instrumentation/instruments.mdx similarity index 90% rename from docs/source/configuration/telemetry/instrumentation/instruments.mdx rename to docs/source/reference/router/telemetry/instrumentation/instruments.mdx index 0e612a30a3..ecec8d1852 100644 --- a/docs/source/configuration/telemetry/instrumentation/instruments.mdx +++ b/docs/source/reference/router/telemetry/instrumentation/instruments.mdx @@ -4,8 +4,8 @@ subtitle: Collect measurements with standard and custom instruments description: Create and customize instruments to collect data and report measurements from the Apollo GraphOS Router's request lifecycle services. --- -import RouterServices from '../../../../shared/router-lifecycle-services.mdx'; -import TelemetryPerformanceNote from '../../../../shared/telemetry-performance.mdx'; +import RouterServices from '../../../../../shared/router-lifecycle-services.mdx'; +import TelemetryPerformanceNote from '../../../../../shared/telemetry-performance.mdx'; An _instrument_ in the router collects data and reports measurements to a metric backend. Supported instruments include standard instruments from OpenTelemetry, standard instruments for the router's request lifecycle, and custom instruments. Supported instrument kinds are counters and histograms. @@ -27,6 +27,11 @@ OpenTelemetry specifies multiple [standard metric instruments](https://opentelem * `http.client.request.duration` - A histogram of request durations for requests handled by subgraphs. * `http.client.response.body.size` - A histogram of response body sizes for requests handled by subgraphs. + + +The [`default_requirement_level` setting](#default_requirement_level) configures whether or not these instruments are enabled by default. Out of the box, its default value of `required` enables them. You must explicitly configure an instrument for different behavior. + + These instruments are configurable in `router.yaml`: @@ -63,7 +68,7 @@ telemetry: ### Apollo standard instruments -To learn about Apollo-provided standard metric instruments for the router's request lifecycle, see [router instruments](./standard-instruments). +To learn about Apollo-provided standard metric instruments for the router's request lifecycle, see [router instruments](/router/configuration/telemetry/instrumentation/standard-instruments). ### Custom instruments @@ -309,7 +314,7 @@ The [service](#router-request-lifecycle-services) you define an instrument on de -`event_*` are mandantory when you want to use a [selector](./selectors) on the supergraph response body (`response_data` and `response_errors`). +`event_*` are mandantory when you want to use a [selector](/router/configuration/telemetry/instrumentation/selectors) on the supergraph response body (`response_data` and `response_errors`). @@ -403,7 +408,7 @@ telemetry: Instruments may have attributes attached to them from the router pipeline. These attributes are used to filter and group metrics in your APM. -Attributes may be drawn from [standard attributes](./standard-attributes) or [selectors](./selectors) except for the standard metric `http.server.active_requests`. +Attributes may be drawn from [standard attributes](/router/configuration/telemetry/instrumentation/standard-attributes) or [selectors](/router/configuration/telemetry/instrumentation/selectors) except for the standard metric `http.server.active_requests`. The attributes available depend on the service of the pipeline. @@ -469,8 +474,8 @@ telemetry: |-----------------------------|--------------------------------------------------------------------------------|------------|-----------------------------------------------| | `` | | | The name of the custom attribute. | | `` | | | The name of the custom instrument. | -| `attributes` | [standard attributes](./standard-attributes) or [selectors](./selectors) | | The attributes of the custom instrument. | -| `condition` | [conditions](./conditions) | | The condition for mutating the instrument. | +| `attributes` | [standard attributes](/router/configuration/telemetry/instrumentation/standard-attributes) or [selectors](/router/configuration/telemetry/instrumentation/selectors) | | The attributes of the custom instrument. | +| `condition` | [conditions](/router/configuration/telemetry/instrumentation/conditions) | | The condition for mutating the instrument. | | `default_requirement_level` | `required`\|`recommended` | `required` | The default attribute requirement level. | | `type` | `counter`\|`histogram` | | The name of the custom instrument. | | `unit` | | | A unit name, for example `By` or `{request}`. | diff --git a/docs/source/configuration/telemetry/instrumentation/selectors.mdx b/docs/source/reference/router/telemetry/instrumentation/selectors.mdx similarity index 96% rename from docs/source/configuration/telemetry/instrumentation/selectors.mdx rename to docs/source/reference/router/telemetry/instrumentation/selectors.mdx index 312375f26c..580ed124ca 100644 --- a/docs/source/configuration/telemetry/instrumentation/selectors.mdx +++ b/docs/source/reference/router/telemetry/instrumentation/selectors.mdx @@ -3,9 +3,9 @@ title: Selectors subtitle: Select data from the router pipeline to extract description: Extract and select data from the Apollo GraphOS Router's pipeline services to attach to telemetry. --- -import RouterServices from '../../../../shared/router-lifecycle-services.mdx'; +import RouterServices from '../../../../../shared/router-lifecycle-services.mdx'; -A _selector_ is used to extract data from the GraphOS Router's request lifecycle (pipeline) services and attach them to telemetry. Specifically [spans](./spans), [instruments](./instruments), [conditions](./conditions) and [events](./events). +A _selector_ is used to extract data from the GraphOS Router's request lifecycle (pipeline) services and attach them to telemetry, specifically [spans](/router/configuration/telemetry/instrumentation/spans), [instruments](/router/configuration/telemetry/instrumentation/instruments), [conditions](/router/configuration/telemetry/instrumentation/conditions) and [events](/router/configuration/telemetry/instrumentation/events). An example of a selector, `request_header`, of the router service on a custom span attribute: diff --git a/docs/source/configuration/telemetry/instrumentation/spans.mdx b/docs/source/reference/router/telemetry/instrumentation/spans.mdx similarity index 87% rename from docs/source/configuration/telemetry/instrumentation/spans.mdx rename to docs/source/reference/router/telemetry/instrumentation/spans.mdx index 73dddd58e0..70016ebdb0 100644 --- a/docs/source/configuration/telemetry/instrumentation/spans.mdx +++ b/docs/source/reference/router/telemetry/instrumentation/spans.mdx @@ -4,9 +4,9 @@ subtitle: Add router lifecycle context to traces description: Use spans to add contextual information from the Apollo GraphOS Router or Apollo Router Core to traces displayed by your application performance monitors (APM). --- -import RouterServices from '../../../../shared/router-lifecycle-services.mdx'; +import RouterServices from '../../../../../shared/router-lifecycle-services.mdx'; -A **span** captures contextual information about requests and responses as they're processed through the [router's request lifecycle (pipeline)](../../../customizations/overview/#the-request-lifecycle). The information from spans can be used when displaying traces in your application performance monitors (APM). +A **span** captures contextual information about requests and responses as they're processed through the [router's request lifecycle (pipeline)](/router/customizations/overview/#the-request-lifecycle). The information from spans can be used when displaying traces in your application performance monitors (APM). ## Spans configuration @@ -35,7 +35,7 @@ telemetry: Spans may have attributes attached to them from the router pipeline. These attributes are used to filter and group spans in your APM. -Attributes may be drawn from [standard attributes](./standard-attributes) or [selectors](./selectors). +Attributes may be drawn from [standard attributes](/router/configuration/telemetry/instrumentation/standard-attributes) or [selectors](/router/configuration/telemetry/instrumentation/selectors). @@ -58,7 +58,7 @@ telemetry: response_header: "x-my-header" ``` -You can also have [conditions](./conditions) on custom attributes using [selectors](./selectors). You can only have conditions on a selector at the same execution level. +You can also have [conditions](/router/configuration/telemetry/instrumentation/conditions) on custom attributes using [selectors](/router/configuration/telemetry/instrumentation/selectors). You can only have conditions on a selector at the same execution level. Example you can't have a condition on `response_header` if you want to set an attribute from `request_header`. ```yaml title="desc.router.yaml" @@ -245,8 +245,8 @@ telemetry: | Option | Values | Default | Description | |---------------------------------------|---------------------------------------------------------------------------|--------------------------------|------------------------------------------| | `` | | | The name of the custom attribute. | -| `attributes` | [standard attributes](./standard-attributes)\|[selectors](./selectors) | | The attributes of the span. | -| `condition` | [conditions](./conditions) | | The condition for adding a custom attribute. | +| `attributes` | [standard attributes](/router/configuration/telemetry/instrumentation/standard-attributes)\|[selectors](/router/configuration/telemetry/instrumentation/selectors) | | The attributes of the span. | +| `condition` | [conditions](/router/configuration/telemetry/instrumentation/conditions) | | The condition for adding a custom attribute. | | `default_attribute_requirement_level` | `required`\|`recommended` | `required` | The default attribute requirement level. | | `mode` | `spec_compliant` \| `deprecated` | `deprecated` | The attributes of the span. | diff --git a/docs/source/configuration/telemetry/instrumentation/standard-attributes.mdx b/docs/source/reference/router/telemetry/instrumentation/standard-attributes.mdx similarity index 89% rename from docs/source/configuration/telemetry/instrumentation/standard-attributes.mdx rename to docs/source/reference/router/telemetry/instrumentation/standard-attributes.mdx index 5df84f52bf..b1440ca115 100644 --- a/docs/source/configuration/telemetry/instrumentation/standard-attributes.mdx +++ b/docs/source/reference/router/telemetry/instrumentation/standard-attributes.mdx @@ -4,9 +4,9 @@ subtitle: Attach standard attributes to router telemetry description: Attach OpenTelemetry (OTel) standard attributes to Apollo GraphOS Router or Apollo Router Core telemetry. --- -import RouterServices from '../../../../shared/router-lifecycle-services.mdx'; +import RouterServices from '../../../../../shared/router-lifecycle-services.mdx'; -[OpenTelemetry semantic conventions](https://opentelemetry.io/docs/specs/semconv/) define a set of **standard attributes** that can be attached to [spans](./spans), [instruments](./instruments) and [events](./events). These attributes are used to filter and group data in your application performance monitor (APM). +[OpenTelemetry semantic conventions](https://opentelemetry.io/docs/specs/semconv/) define a set of **standard attributes** that can be attached to [spans](/router/configuration/telemetry/instrumentation/spans), [instruments](/router/configuration/telemetry/instrumentation/instruments) and [events](/router/configuration/telemetry/instrumentation/events). These attributes are used to filter and group data in your application performance monitor (APM). The attributes available depend on the service of the router pipeline. @@ -93,9 +93,9 @@ Standard attributes of the `supergraph` service: | Attribute | Values | Description | |-----------------------------|-------------------------------------|---------------------------------------------| -| `graphql.operation.name` | | The operation name from the graphql query (need `spec_compliant` [mode](./spans/#mode) to disable it) | +| `graphql.operation.name` | | The operation name from the graphql query (need `spec_compliant` [mode](/router/configuration/telemetry/instrumentation/spans/#mode) to disable it) | | `graphql.operation.type` | `query`\|`mutation`\|`subscription` | The operation kind from the subgraph query | -| `graphql.document` | | The GraphQL query to the subgraph (need `spec_compliant` [mode](./spans/#mode) to disable it) | +| `graphql.document` | | The GraphQL query to the subgraph (need `spec_compliant` [mode](/router/configuration/telemetry/instrumentation/spans/#mode) to disable it) | #### Subgraph @@ -104,7 +104,7 @@ Standard attributes of the `subgraph` service: | Attribute | Values | Description | |------------------------------------|-------------------------------------|------------------------------------------------| -| `subgraph.name` | | The name of the subgraph (need `spec_compliant` [mode](./spans/#mode) to disable it) | -| `subgraph.graphql.operation.name` | | The operation name from the subgraph query (need `spec_compliant` [mode](./spans/#mode) to disable it) | +| `subgraph.name` | | The name of the subgraph (need `spec_compliant` [mode](/router/configuration/telemetry/instrumentation/spans/#mode) to disable it) | +| `subgraph.graphql.operation.name` | | The operation name from the subgraph query (need `spec_compliant` [mode](/router/configuration/telemetry/instrumentation/spans/#mode) to disable it) | | `subgraph.graphql.operation.type` | `query`\|`mutation`\|`subscription` | The operation kind from the subgraph query | -| `subgraph.graphql.document` | | The GraphQL query to the subgraph (need `spec_compliant` [mode](./spans/#mode) to disable it) | +| `subgraph.graphql.document` | | The GraphQL query to the subgraph (need `spec_compliant` [mode](/router/configuration/telemetry/instrumentation/spans/#mode) to disable it) | diff --git a/docs/source/configuration/telemetry/instrumentation/standard-instruments.mdx b/docs/source/reference/router/telemetry/instrumentation/standard-instruments.mdx similarity index 97% rename from docs/source/configuration/telemetry/instrumentation/standard-instruments.mdx rename to docs/source/reference/router/telemetry/instrumentation/standard-instruments.mdx index 7f10f228c1..bf0101d802 100644 --- a/docs/source/configuration/telemetry/instrumentation/standard-instruments.mdx +++ b/docs/source/reference/router/telemetry/instrumentation/standard-instruments.mdx @@ -8,7 +8,7 @@ description: Reference of standard metric instruments for the request lifecycle GraphOS Router and Apollo Router Core provide a set of non-configurable metric instruments that expose detailed information about the router's request lifecycle. -These instruments can be consumed by configuring a [metrics exporter](../exporters/metrics/overview). +These instruments can be consumed by configuring a [metrics exporter](/router/configuration/telemetry/exporters/metrics/overview). ### HTTP @@ -98,7 +98,7 @@ The initial call to Uplink during router startup is not reflected in metrics. -[Learn more about subscriptions.](../../../executing-operations/subscription-support/) +[Learn more about subscriptions.](/router/executing-operations/subscription-support/) diff --git a/docs/source/configuration/telemetry/exporters/logging/overview.mdx b/docs/source/reference/router/telemetry/log-exporters/overview.mdx similarity index 97% rename from docs/source/configuration/telemetry/exporters/logging/overview.mdx rename to docs/source/reference/router/telemetry/log-exporters/overview.mdx index 3f763ac437..f1cef8cff1 100644 --- a/docs/source/configuration/telemetry/exporters/logging/overview.mdx +++ b/docs/source/reference/router/telemetry/log-exporters/overview.mdx @@ -6,7 +6,7 @@ description: Configure logging in the Apollo GraphOS Router or Apollo Router Cor GraphOS Router and Apollo Router Core provide built-in logging to capture records about their activity. -The router supports [configurable log levels](#log-level) and [stdout output](./stdout) of log messages (with [configurable output formats](./stdout/#logging-output-format)). +The router supports [configurable log levels](#log-level) and [stdout output](/router/configuration/telemetry/exporters/logging/stdout) of log messages (with [configurable output formats](/router/configuration/telemetry/exporters/logging/stdout/#logging-output-format)). ## Log level diff --git a/docs/source/configuration/telemetry/exporters/logging/stdout.mdx b/docs/source/reference/router/telemetry/log-exporters/stdout.mdx similarity index 97% rename from docs/source/configuration/telemetry/exporters/logging/stdout.mdx rename to docs/source/reference/router/telemetry/log-exporters/stdout.mdx index a85e8162a6..fddae9b1be 100644 --- a/docs/source/configuration/telemetry/exporters/logging/stdout.mdx +++ b/docs/source/reference/router/telemetry/log-exporters/stdout.mdx @@ -6,7 +6,7 @@ description: Configure logging output to stdout in the Apollo GraphOS Router or You can configure GraphOS Router or Apollo Router Core logging to be directed to stdout, and its output format can be set to text or JSON. -For general logging configuration, refer to [Router Logging Configuration](./overview). +For general logging configuration, refer to [Router Logging Configuration](/router/configuration/telemetry/exporters/logging/overview). ## stdout configuration @@ -31,7 +31,7 @@ You can configure the logging output format. The default format depends on how t * In an interactive shell, [`text`](#text) is the default. * In a non-interactive shell, [`json`](#json) is the default. -You can explicitly set the format in [`router.yaml`](../../../overview#yaml-config-file) with `telemetry.exporters.logging.stdout.format`: +You can explicitly set the format in [`router.yaml`](/router/configuration/overview#yaml-config-file) with `telemetry.exporters.logging.stdout.format`: ```yaml title="router.yaml" telemetry: @@ -51,7 +51,7 @@ If both `format` and `tty_format` are configured then the output depends on the * In an interactive shell, `tty_format` will take precedence. * In a non-interactive shell, `format` will take precedence. -You can explicitly set the format in [`router.yaml`](../../../overview#yaml-config-file) with `telemetry.exporters.logging.stdout.tty_format`: +You can explicitly set the format in [`router.yaml`](/router/configuration/overview#yaml-config-file) with `telemetry.exporters.logging.stdout.tty_format`: ```yaml title="router.yaml" telemetry: diff --git a/docs/source/configuration/telemetry/exporters/metrics/datadog.mdx b/docs/source/reference/router/telemetry/metrics-exporters/datadog.mdx similarity index 74% rename from docs/source/configuration/telemetry/exporters/metrics/datadog.mdx rename to docs/source/reference/router/telemetry/metrics-exporters/datadog.mdx index 5ec3ed40df..4aa7850a76 100644 --- a/docs/source/configuration/telemetry/exporters/metrics/datadog.mdx +++ b/docs/source/reference/router/telemetry/metrics-exporters/datadog.mdx @@ -4,9 +4,9 @@ subtitle: Configure the Datadog exporter for metrics description: Configure the Datadog exporter for metrics via OpenTelemetry Protocol (OTLP) in the Apollo GraphOS Router or Apollo Router Core. --- -Enable and configure the [OTLP exporter](./otlp) for metrics in the GraphOS Router or Apollo Router Core for use with [Datadog](https://www.datadoghq.com/). +Enable and configure the [OTLP exporter](/router/configuration/telemetry/exporters/metrics/otlp) for metrics in the GraphOS Router or Apollo Router Core for use with [Datadog](https://www.datadoghq.com/). -For general tracing configuration, refer to [Router Metrics Configuration](./overview). +For general tracing configuration, refer to [Router Metrics Configuration](/router/configuration/telemetry/exporters/metrics/overview). ## Datadog configuration @@ -28,7 +28,7 @@ otlp_config: ``` ### Router configuration -To configure the router, enable the [OTLP exporter](./otlp#configuration) and set both `temporality: delta` and `endpoint: `. For example: +To configure the router, enable the [OTLP exporter](/router/configuration/telemetry/exporters/metrics/otlp#configuration) and set both `temporality: delta` and `endpoint: `. For example: ```yaml title="router.yaml" telemetry: diff --git a/docs/source/configuration/telemetry/exporters/metrics/dynatrace.mdx b/docs/source/reference/router/telemetry/metrics-exporters/dynatrace.mdx similarity index 85% rename from docs/source/configuration/telemetry/exporters/metrics/dynatrace.mdx rename to docs/source/reference/router/telemetry/metrics-exporters/dynatrace.mdx index dfd00f1c8d..fedb7f9e90 100644 --- a/docs/source/configuration/telemetry/exporters/metrics/dynatrace.mdx +++ b/docs/source/reference/router/telemetry/metrics-exporters/dynatrace.mdx @@ -4,15 +4,15 @@ subtitle: Configure the Dynatrace exporter for metrics description: Configure the Dynatrace exporter for metrics via OpenTelemetry Protocol (OTLP) in the Apollo Router. --- -Enable and configure the [OTLP exporter](./otlp) for metrics in the Apollo Router for use with [Dynatrace](https://dynatrace.com/). +Enable and configure the [OTLP exporter](/router/configuration/telemetry/exporters/metrics/otlp) for metrics in the Apollo Router for use with [Dynatrace](https://dynatrace.com/). -For general tracing configuration, refer to [Router Metrics Configuration](./overview). +For general tracing configuration, refer to [Router Metrics Configuration](/router/configuration/telemetry/exporters/metrics/overview). ## Dynatrace configuration To configure the router: -- Enable the [OTLP exporter](./otlp#configuration) +- Enable the [OTLP exporter](/router/configuration/telemetry/exporters/metrics/otlp#configuration) - Set `temporality: delta` (Using _Delta_ is required as _Cumulative_ temporality is **not** supported by Dynatrace) - Set the `protocol` as `http` (Dynatrace [doesn't currently support](https://docs.dynatrace.com/docs/extend-dynatrace/opentelemetry/getting-started/otlp-export) gRPC) - Set the `endpoint` to your [Dynatrace OpenTelemetry metrics endpoint](https://docs.dynatrace.com/docs/dynatrace-api/environment-api/opentelemetry/post-metrics) (e.g., ensuring that it contains `{your-environment-id}` in the hostname and ends in `/api/v2/otlp/v1/metrics`) diff --git a/docs/source/configuration/telemetry/exporters/metrics/new-relic.mdx b/docs/source/reference/router/telemetry/metrics-exporters/new-relic.mdx similarity index 71% rename from docs/source/configuration/telemetry/exporters/metrics/new-relic.mdx rename to docs/source/reference/router/telemetry/metrics-exporters/new-relic.mdx index 2d4892fb80..656360e73c 100644 --- a/docs/source/configuration/telemetry/exporters/metrics/new-relic.mdx +++ b/docs/source/reference/router/telemetry/metrics-exporters/new-relic.mdx @@ -4,13 +4,13 @@ subtitle: Configure the New Relic exporter for metrics description: Configure the New Relic exporter for metrics via OpenTelemetry Protocol (OTLP) in the Apollo GraphOS Router or Apollo Router Core. --- -Enable and configure the [OTLP exporter](./otlp) for metrics in the GraphOS Router or Apollo Router Core for use with [New Relic](https://newrelic.com/). +Enable and configure the [OTLP exporter](/router/configuration/telemetry/exporters/metrics/otlp) for metrics in the GraphOS Router or Apollo Router Core for use with [New Relic](https://newrelic.com/). -For general metrics configuration, refer to [Router Metrics Configuration](./overview). +For general tracing configuration, refer to [Router Metrics Configuration](/router/configuration/telemetry/exporters/metrics/overview). ## New Relic configuration -To configure the router, enable the [OTLP exporter](./otlp#configuration) with `temporality: delta` and the appropriate endpoint and New Relic API key. +To configure the router, enable the [OTLP exporter](/router/configuration/telemetry/exporters/metrics/otlp#configuration) with `temporality: delta` and the appropriate endpoint and New Relic API key. diff --git a/docs/source/configuration/telemetry/exporters/metrics/otlp.mdx b/docs/source/reference/router/telemetry/metrics-exporters/otlp.mdx similarity index 92% rename from docs/source/configuration/telemetry/exporters/metrics/otlp.mdx rename to docs/source/reference/router/telemetry/metrics-exporters/otlp.mdx index 8699cfe5b4..08042c405a 100644 --- a/docs/source/configuration/telemetry/exporters/metrics/otlp.mdx +++ b/docs/source/reference/router/telemetry/metrics-exporters/otlp.mdx @@ -8,13 +8,13 @@ import BatchProcessorRef from '../../../../../shared/batch-processor-ref.mdx'; Enable and configure the [OpenTelemetry Protocol (OTLP)](https://www.opentelemetry.io/) exporter for metrics in the GraphOS Router or Apollo Router Core. -For general metrics configuration, refer to [Router Metrics Configuration](./overview). +For general metrics configuration, refer to [Router Metrics Configuration](/router/configuration/telemetry/exporters/metrics/overview). Using the OTLP protocol, you can export metrics to any OTLP compatible receiver, including: * [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/) -* [Datadog](https://www.datadoghq.com/) (see [configuration instructions](./datadog)) -* [New Relic](https://www.newrelic.com/) (see [configuration instructions](./new-relic)) +* [Datadog](https://www.datadoghq.com/) (see [configuration instructions](/router/configuration/telemetry/exporters/metrics/datadog)) +* [New Relic](https://www.newrelic.com/) (see [configuration instructions](/router/configuration/telemetry/exporters/metrics/new-relic)) ## OTLP configuration @@ -85,7 +85,7 @@ telemetry: -Use the [variable expansion feature](../../../overview#variable-expansion) for referencing environment variables and file paths in YAML configuration files. Use `env.` and `file.` prefixes, for example `${file.ca.txt}`. +Use the [variable expansion feature](/router/configuration/overview#variable-expansion) for referencing environment variables and file paths in YAML configuration files. Use `env.` and `file.` prefixes, for example `${file.ca.txt}`. diff --git a/docs/source/configuration/telemetry/exporters/metrics/overview.mdx b/docs/source/reference/router/telemetry/metrics-exporters/overview.mdx similarity index 89% rename from docs/source/configuration/telemetry/exporters/metrics/overview.mdx rename to docs/source/reference/router/telemetry/metrics-exporters/overview.mdx index b8a2cb256f..efb22e3ccc 100644 --- a/docs/source/configuration/telemetry/exporters/metrics/overview.mdx +++ b/docs/source/reference/router/telemetry/metrics-exporters/overview.mdx @@ -2,16 +2,18 @@ title: Metrics exporters subtitle: Export router metrics description: Collect and export metrics from the Apollo GraphOS Router or Apollo Router Core for Prometheus, OpenTelemetry Protocol (OTLP), Datadog, and New Relic. +redirectFrom: + - /technotes/TN0015-router-to-apm-via-opentelemetry/ --- The GraphOS Router and Apollo Router Core support collection of metrics with [OpenTelemetry](https://opentelemetry.io/), with exporters for: -* [Prometheus](./prometheus) -* [OpenTelemetry Protocol (OTLP)](./otlp) -* [Datadog via OTLP](./datadog) -* [New Relic via OTLP](./new-relic) +* [Prometheus](/router/configuration/telemetry/exporters/metrics/prometheus) +* [OpenTelemetry Protocol (OTLP)](/router/configuration/telemetry/exporters/metrics/otlp) +* [Datadog via OTLP](/router/configuration/telemetry/exporters/metrics/datadog) +* [New Relic via OTLP](/router/configuration/telemetry/exporters/metrics/new-relic) -In [`router.yaml`](../../../overview/#yaml-config-file), you configure router metrics with the following settings: +In [`router.yaml`](/router/configuration/overview/#yaml-config-file), you configure router metrics with the following settings: - `telemetry.exporters.metrics.common`. Configure values for the router which are common across metrics exporters. - `telemetry.exporters.metrics.prometheus`. Configure the Prometheus exporter. @@ -31,7 +33,7 @@ Common metrics configuration contains global settings for all exporters: Set a service name for your router metrics so you can easily locate them in external metrics dashboards. -The service name can be set by an environment variable or in [`router.yaml`](../../../overview/#yaml-config-file), with the following order of precedence (first to last): +The service name can be set by an environment variable or in [`router.yaml`](/router/configuration/overview/#yaml-config-file), with the following order of precedence (first to last): 1. `OTEL_SERVICE_NAME` environment variable 2. `OTEL_RESOURCE_ATTRIBUTES` environment variable @@ -77,7 +79,7 @@ If the service name isn't explicitly set, it defaults to `unknown_service:router A resource attribute is a set of key-value pairs that provide additional information to an exporter. It's an attribute of an [OpenTelemetry resource](https://opentelemetry.io/docs/specs/otel/resource/sdk/). Application performance monitors (APM) can interpret and display resource information. -In [`router.yaml`](../../../overview/#yaml-config-file), resource attributes are set in `telemetry.metrics.common.resource`. For example: +In [`router.yaml`](/router/configuration/overview/#yaml-config-file), resource attributes are set in `telemetry.metrics.common.resource`. For example: ```yaml title="router.yaml" telemetry: @@ -94,7 +96,7 @@ For OpenTelemetry conventions for resources, see [Resource Semantic Conventions] ### `buckets` -You can customize bucket boundaries for all generated histograms by setting `telemetry.exporters.metrics.common.buckets` in [`router.yaml`](../../../overview/#yaml-config-file). For example: +You can customize bucket boundaries for all generated histograms by setting `telemetry.exporters.metrics.common.buckets` in [`router.yaml`](/router/configuration/overview/#yaml-config-file). For example: ```yaml title="router.yaml" telemetry: @@ -186,7 +188,7 @@ telemetry: -OpenTelemetry includes many [standard attributes](https://opentelemetry.io/docs/specs/semconv/attributes-registry/) that you can use via custom [instruments](../../instrumentation/instruments). +OpenTelemetry includes many [standard attributes](https://opentelemetry.io/docs/specs/semconv/attributes-registry/) that you can use via custom [instruments](/router/configuration/telemetry/instrumentation/instruments). @@ -245,4 +247,4 @@ telemetry: ## Related topics * [Connecting OpenTelemetry traces to Prometheus](/technotes/TN0003-opentelemetry-traces-to-prometheus) -* [Sending router traces and metrics to APM tools using OpenTelemetry](/technotes/TN0015-router-to-apm-via-opentelemetry/) +* [Sending router traces and metrics to APM tools using OpenTelemetry](/graphos/reference/router/telemetry/metrics-exporters/overview) diff --git a/docs/source/configuration/telemetry/exporters/metrics/prometheus.mdx b/docs/source/reference/router/telemetry/metrics-exporters/prometheus.mdx similarity index 94% rename from docs/source/configuration/telemetry/exporters/metrics/prometheus.mdx rename to docs/source/reference/router/telemetry/metrics-exporters/prometheus.mdx index 185276a0b7..3123714d14 100644 --- a/docs/source/configuration/telemetry/exporters/metrics/prometheus.mdx +++ b/docs/source/reference/router/telemetry/metrics-exporters/prometheus.mdx @@ -6,11 +6,11 @@ description: Configure the Prometheus metrics exporter endpoint in the Apollo Gr Enable and configure the [Prometheus](https://www.prometheus.io/) exporter for metrics in the GraphOS Router or Apollo Router Core. -For general metrics configuration, refer to [Router Metrics Configuration](./overview). +For general metrics configuration, refer to [Router Metrics Configuration](/router/configuration/telemetry/exporters/metrics/overview). ## Prometheus configuration -To export metrics to Prometheus, enable the Prometheus endpoint and set its address and path in [`router.yaml`](../../../overview#yaml-config-file): +To export metrics to Prometheus, enable the Prometheus endpoint and set its address and path in [`router.yaml`](/router/configuration/overview#yaml-config-file): ```yaml title="router.yaml" telemetry: diff --git a/docs/source/configuration/telemetry/exporters/tracing/datadog.mdx b/docs/source/reference/router/telemetry/trace-exporters/datadog.mdx similarity index 97% rename from docs/source/configuration/telemetry/exporters/tracing/datadog.mdx rename to docs/source/reference/router/telemetry/trace-exporters/datadog.mdx index 0eea7691d9..e1b105d338 100644 --- a/docs/source/configuration/telemetry/exporters/tracing/datadog.mdx +++ b/docs/source/reference/router/telemetry/trace-exporters/datadog.mdx @@ -8,7 +8,7 @@ import BatchProcessorRef from '../../../../../shared/batch-processor-ref.mdx'; Enable and configure the [Datadog](https://www.datadoghq.com/) exporter for tracing in the GraphOS Router or Apollo Router Core. -For general tracing configuration, refer to [Router Tracing Configuration](./overview). +For general tracing configuration, refer to [Router Tracing Configuration](/router/configuration/telemetry/exporters/tracing/overview). ## OTLP configuration @@ -26,7 +26,7 @@ otlp_config: endpoint: :4317 ``` -To configure the router, enable the [OTLP exporter](./otlp) and set `endpoint: `. For example: +To configure the router, enable the [OTLP exporter](/router/configuration/telemetry/exporters/tracing/otlp) and set `endpoint: `. For example: ```yaml title="router.yaml" telemetry: diff --git a/docs/source/configuration/telemetry/exporters/tracing/dynatrace.mdx b/docs/source/reference/router/telemetry/trace-exporters/dynatrace.mdx similarity index 81% rename from docs/source/configuration/telemetry/exporters/tracing/dynatrace.mdx rename to docs/source/reference/router/telemetry/trace-exporters/dynatrace.mdx index 2ba82a6358..db736561d4 100644 --- a/docs/source/configuration/telemetry/exporters/tracing/dynatrace.mdx +++ b/docs/source/reference/router/telemetry/trace-exporters/dynatrace.mdx @@ -4,15 +4,15 @@ subtitle: Configure the Dynatrace exporter for tracing description: Configure the Dynatrace exporter for tracing via OpenTelemetry Protocol (OTLP) in the Apollo Router. --- -Enable and configure the [OTLP exporter](./otlp) for tracing in the Apollo Router for use with [Dynatrace](https://dynatrace.com/). +Enable and configure the [OTLP exporter](/router/configuration/telemetry/exporters/tracing/otlp) for tracing in the Apollo Router for use with [Dynatrace](https://dynatrace.com/). -For general tracing configuration, refer to [Router Tracing Configuration](./overview). +For general tracing configuration, refer to [Router Tracing Configuration](/router/configuration/telemetry/exporters/tracing/overview). ## Dynatrace configuration To configure the router: -- Enable the [OTLP exporter](./otlp#configuration) +- Enable the [OTLP exporter](/router/configuration/telemetry/exporters/tracing/otlp#configuration) - Set the `protocol` as `http`; Dynatrace [doesn't currently support](https://docs.dynatrace.com/docs/extend-dynatrace/opentelemetry/getting-started/otlp-export) `grpc` - Provide your Dynatrace endpoint - Provide your Dynatrace API token in the `Authorization` header; the header should start with [`Api-token` and then your Dynatrace token](https://docs.dynatrace.com/docs/extend-dynatrace/opentelemetry/getting-started/otlp-export#authentication-export-to-activegate) diff --git a/docs/source/configuration/telemetry/exporters/tracing/jaeger.mdx b/docs/source/reference/router/telemetry/trace-exporters/jaeger.mdx similarity index 95% rename from docs/source/configuration/telemetry/exporters/tracing/jaeger.mdx rename to docs/source/reference/router/telemetry/trace-exporters/jaeger.mdx index 7c29456231..28199ec84d 100644 --- a/docs/source/configuration/telemetry/exporters/tracing/jaeger.mdx +++ b/docs/source/reference/router/telemetry/trace-exporters/jaeger.mdx @@ -9,7 +9,7 @@ import BatchProcessorRef from '../../../../../shared/batch-processor-ref.mdx'; Enable and configure the [Jaeger exporter](https://www.jaegertracing.io/) for tracing in the GraphOS Router or Apollo Router Core. -For general tracing configuration, refer to [Router Tracing Configuration](./overview). +For general tracing configuration, refer to [Router Tracing Configuration](/router/configuration/telemetry/exporters/tracing/overview). ## Jaeger OTLP configuration @@ -38,7 +38,7 @@ telemetry: endpoint: "http://${env.JAEGER_HOST}:4317" ``` -See [OTLP configuration](./otlp#configuration) for more details on settings. +See [OTLP configuration](/router/configuration/telemetry/exporters/tracing/otlp#configuration) for more details on settings. ## Jaeger Native configuration diff --git a/docs/source/configuration/telemetry/exporters/tracing/new-relic.mdx b/docs/source/reference/router/telemetry/trace-exporters/new-relic.mdx similarity index 64% rename from docs/source/configuration/telemetry/exporters/tracing/new-relic.mdx rename to docs/source/reference/router/telemetry/trace-exporters/new-relic.mdx index 532816c1df..6afde09486 100644 --- a/docs/source/configuration/telemetry/exporters/tracing/new-relic.mdx +++ b/docs/source/reference/router/telemetry/trace-exporters/new-relic.mdx @@ -4,13 +4,13 @@ subtitle: Configure the New Relic exporter for tracing description: Configure the New Relic exporter for tracing via OpenTelemetry Protocol (OTLP) in the Apollo GraphOS Router or Apollo Router Core. --- -Enable and configure the [OTLP exporter](./otlp) for tracing in the GraphOS Router or Apollo Router Core for use with [New Relic](https://newrelic.com/). +Enable and configure the [OTLP exporter](/router/configuration/telemetry/exporters/tracing/otlp) for tracing in the GraphOS Router or Apollo Router Core for use with [New Relic](https://newrelic.com/). -For general tracing configuration, refer to [Router Tracing Configuration](./overview). +For general tracing configuration, refer to [Router Tracing Configuration](/router/configuration/telemetry/exporters/tracing/overview). ## New Relic configuration -To configure the router, enable the [OTLP exporter](./otlp/#otlp-configuration) and set both `endpoint: ` and `api-key: `. For example: +To configure the router, enable the [OTLP exporter](/router/configuration/telemetry/exporters/tracing/otlp/#otlp-configuration) and set both `endpoint: ` and `api-key: `. For example: ```yaml title="router.yaml" telemetry: diff --git a/docs/source/configuration/telemetry/exporters/tracing/otlp.mdx b/docs/source/reference/router/telemetry/trace-exporters/otlp.mdx similarity index 90% rename from docs/source/configuration/telemetry/exporters/tracing/otlp.mdx rename to docs/source/reference/router/telemetry/trace-exporters/otlp.mdx index dca5ea60c5..fa7ff3a39e 100644 --- a/docs/source/configuration/telemetry/exporters/tracing/otlp.mdx +++ b/docs/source/reference/router/telemetry/trace-exporters/otlp.mdx @@ -11,11 +11,11 @@ Enable and configure the [OpenTelemetry Protocol (OTLP)](https://github.com/open OTLP is the native protocol for OpenTelemetry. It can be used to export traces over HTTP or gRPC to a variety of backends including: * [OpenTelemetry Collector](https://opentelemetry.io/docs/collector/) -* [Datadog](./datadog) -* [Jaeger](./jaeger) -* [New Relic](./new-relic) +* [Datadog](/router/configuration/telemetry/exporters/tracing/datadog) +* [Jaeger](/router/configuration/telemetry/exporters/tracing/jaeger) +* [New Relic](/router/configuration/telemetry/exporters/tracing/new-relic) -For general tracing configuration, refer to [Router Tracing Configuration](./overview). +For general tracing configuration, refer to [Router Tracing Configuration](/router/configuration/telemetry/exporters/tracing/overview). ## OTLP configuration @@ -81,7 +81,7 @@ telemetry: -Use the [variable expansion feature](../../overview#variable-expansion) for referencing environment variables and file paths in YAML configuration files. Use `env.` and `file.` prefixes, for example `${file.ca.txt}`. +Use the [variable expansion feature](/router/configuration/overview#variable-expansion) for referencing environment variables and file paths in YAML configuration files. Use `env.` and `file.` prefixes, for example `${file.ca.txt}`. diff --git a/docs/source/configuration/telemetry/exporters/tracing/overview.mdx b/docs/source/reference/router/telemetry/trace-exporters/overview.mdx similarity index 90% rename from docs/source/configuration/telemetry/exporters/tracing/overview.mdx rename to docs/source/reference/router/telemetry/trace-exporters/overview.mdx index c7b81cca70..ecbabb800d 100644 --- a/docs/source/configuration/telemetry/exporters/tracing/overview.mdx +++ b/docs/source/reference/router/telemetry/trace-exporters/overview.mdx @@ -6,13 +6,13 @@ description: Collect and export tracing information from the Apollo GraphOS Rout The GraphOS Router and Apollo Router Core support collection of traces with [OpenTelemetry](https://opentelemetry.io/), with exporters for: -* [Jaeger](./jaeger) -* [Zipkin](./zipkin) -* [Datadog](./datadog) -* [New Relic](./new-relic) -* [OpenTelemetry Protocol (OTLP)](./otlp) over HTTP or gRPC +* [Jaeger](/router/configuration/telemetry/exporters/tracing/jaeger) +* [Zipkin](/router/configuration/telemetry/exporters/tracing/zipkin) +* [Datadog](/router/configuration/telemetry/exporters/tracing/datadog) +* [New Relic](/router/configuration/telemetry/exporters/tracing/new-relic) +* [OpenTelemetry Protocol (OTLP)](/router/configuration/telemetry/exporters/tracing/otlp) over HTTP or gRPC -The router generates [**spans**](../../instrumentation/spans) that include the various phases of serving a request and associated dependencies. This is useful for showing how response time is affected by: +The router generates [**spans**](/router/configuration/telemetry/instrumentation/spans) that include the various phases of serving a request and associated dependencies. This is useful for showing how response time is affected by: * Sub-request response times * Query shape (sub-request dependencies) @@ -34,7 +34,7 @@ Common tracing configuration contains global settings for all exporters. Set a service name for your router traces so you can easily locate them in external metrics dashboards. -The service name can be set by an environment variable or in [`router.yaml`](../../../overview#yaml-config-file), with the following order of precedence (first to last): +The service name can be set by an environment variable or in [`router.yaml`](/router/configuration/overview#yaml-config-file), with the following order of precedence (first to last): 1. `OTEL_SERVICE_NAME` environment variable 2. `OTEL_RESOURCE_ATTRIBUTES` environment variable @@ -80,7 +80,7 @@ If the service name isn't explicitly set, it defaults to `unknown_service:router A resource attribute is a set of key-value pairs that provide additional information to an exporter. Application performance monitors (APM) may interpret and display resource information. -In [`router.yaml`](../../../overview#yaml-config-file), resource attributes are set in `telemetry.exporters.tracing.common.resource`. For example: +In [`router.yaml`](/router/configuration/overview#yaml-config-file), resource attributes are set in `telemetry.exporters.tracing.common.resource`. For example: ```yaml title="router.yaml" telemetry: @@ -96,7 +96,7 @@ For OpenTelemetry conventions for resources, see [Resource Semantic Conventions] ### `sampler` -You can configure the sampling rate of traces to match the rate of your application performance monitors (APM). To enable sampling configuration, in [`router.yaml`](../../../overview#yaml-config-file) set `telemetry.exporters.tracing.common.sampler` and `telemetry.exporters.tracing.common.parent_based_sampler`: +You can configure the sampling rate of traces to match the rate of your application performance monitors (APM). To enable sampling configuration, in [`router.yaml`](/router/configuration/overview#yaml-config-file) set `telemetry.exporters.tracing.common.sampler` and `telemetry.exporters.tracing.common.parent_based_sampler`: ```yaml title="router.yaml" telemetry: @@ -250,4 +250,4 @@ Using this configuration you will have a response header called `my-trace-id` co ## Related topics * [Connecting OpenTelemetry traces to Prometheus](/technotes/TN0003-opentelemetry-traces-to-prometheus) -* [Sending router traces and metrics to APM tools using OpenTelemetry](/technotes/TN0015-router-to-apm-via-opentelemetry/) +* [Sending router traces and metrics to APM tools using OpenTelemetry](/graphos/reference/router/telemetry/metrics-exporters/overview) diff --git a/docs/source/configuration/telemetry/exporters/tracing/zipkin.mdx b/docs/source/reference/router/telemetry/trace-exporters/zipkin.mdx similarity index 96% rename from docs/source/configuration/telemetry/exporters/tracing/zipkin.mdx rename to docs/source/reference/router/telemetry/trace-exporters/zipkin.mdx index 7b286af618..b4a732999e 100644 --- a/docs/source/configuration/telemetry/exporters/tracing/zipkin.mdx +++ b/docs/source/reference/router/telemetry/trace-exporters/zipkin.mdx @@ -8,7 +8,7 @@ import BatchProcessorRef from '../../../../../shared/batch-processor-ref.mdx'; Enable and configure the [Zipkin](https://zipkin.io/) exporter for tracing in the GraphOS Router or Apollo Router Core. -For general tracing configuration, refer to [Router Tracing Configuration](./overview). +For general tracing configuration, refer to [Router Tracing Configuration](/router/configuration/telemetry/exporters/tracing/overview). ## Zipkin configuration diff --git a/docs/source/routing/about-router.mdx b/docs/source/routing/about-router.mdx new file mode 100644 index 0000000000..55a962573e --- /dev/null +++ b/docs/source/routing/about-router.mdx @@ -0,0 +1,150 @@ +--- +title: Supergraph Routing with GraphOS Router +subtitle: Learn the basics about router features and deployment types +description: Apollo provides cloud and self-hosted GraphOS Router options. The router acts as an entry point to your GraphQL APIs and provides a unified interface for clients to interact with. +redirectFrom: + - /graphos/routing + - /federation/query-plans +--- + +## What is GraphOS Router? + +GraphOS Router is the runtime of the GraphOS platform. It executes client operations by planning and executing subgraph queries, then merging them into client responses. It's also the single entry point and gateway to your federated GraphQL API. + + + + +### Runtime of GraphOS platform + +As the runtime of the [GraphOS platform](/graphos/get-started/concepts/graphos), a GraphOS Router gets the supergraph schemaโ€”the blueprint of the federated graphsโ€”from the GraphOS control plane. It then executes incoming clients operations based on that schema. + +Unlike API gateways that offer capabilities to manage API endpoints, the router isn't based on URLs or REST endpoints. Rather, the router is a GraphQL-native solution for handling client APIs. + +### Subgraph query planner + +Whenever your router receives an incoming GraphQL operation, it needs to figure out how to use your subgraphs to populate data for each of that operation's fields. To do this, the router generates a _query plan_: + + + + +A query plan is a blueprint for dividing a single incoming operation into one or more operations that are each resolvable by a single subgraph. Some of these operations depend on the results of other operations, so the query plan also defines any required ordering for their execution. The router's query planner determines the optimal set of subgraph queries for each client operation, then it merges the subgraph responses into a single response for the client. + + + +Use the [Explorer IDE](/graphos/platform/explorer/) to view dynamically calculated example query plans for your operations in its right-hand panel. + + + +### Entry point to federated GraphQL API + +The GraphOS Router is the gateway and entry point to a federated supergraph. Clients send GraphQL operations to your router's public endpoint instead of directly to your APIs. + +## GraphOS Router deployment types + +As the entry point to your supergraph, a GraphOS Router must be able to process the expected load of client operations. The scalability and performance of a router, or a fleet or router instances, can be influenced by their deployment infrastructure. + +### Cloud-hosted routers + +You can choose for Apollo to provision and manage the runtime infrastructure for your routers. Apollo hosts and deploys each instance of router in the cloud. Each _cloud-hosted router_ instance is fully integrated and configurable within GraphOS. + + + + + + +While cloud routers are hosted in the cloud, GraphQL subgraph servers are still hosted in your infrastructure. + + + +### Self-hosted routers + +You can choose to manage the runtime infrastructure for your routers by yourself. Using container images of router, you can host and deploy your router instances from your own infrastructure. These _self-hosted router_ instances allow you full control over their deployment. + + + + +### Common router core + +Both cloud-hosted and self-hosted routers are powered by the [Apollo Router Core](https://github.com/apollographql/router)โ€”a high-performance router packaged as a standalone binary. + +### Router type comparison + +Apollo offers the following router options, in increasing order of configurability: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      Router typeDescriptionConfigurabilityPlan availability
      Shared cloud routerApollo provisions and manages routers on shared infrastructure. + Basic configurability, including HTTP header rules, CORS settings, and + subgraph error inclusion + + Serverless** +
      Dedicated cloud router + Apollo provisions and manages routers on dedicated infrastructure that + you control and scale. + + Highly configurable, including all options for shared cloud routers and + additional configurations + + Dedicated** +
      Self-hosted routerYou host and manage the router on your own infrastructure. + Highly configurable and customizable, including all options for Cloud + Dedicated routers and additional [customization options](/graphos/routing/customization/overview). + + The Apollo Router Core is available as a free and source-available router. + Connecting your self-hosted router to GraphOS requires an{' '} + Enterprise plan. +
      + + + +**We've paused new sign-ups for Serverless and Dedicated plans while we improve our offerings based on user feedback. This means cloud routing is temporarily unavailable to new users. In the meantime, you can explore other GraphOS features with a [free trial](https://studio.apollographql.com/signup?referrer=docs-content). + + + +## GraphOS Router features + +Although powered by the source-available Apollo Router Core binary, GraphOS Routers offer an expanded feature set that isn't available when running the Apollo Router Core without connecting it to GraphOS. + +Cloud-hosted routers automatically have access to additional GraphOS Router features, while self-hosted routers must be authenticated with a GraphOS Enterprise license to gain access to these features. Refer to the [pricing page](https://www.apollographql.com/pricing#graphos-router) to compare GraphOS Router features across plan types. + + +## Next steps + +- Learn more about Apollo-managed routers in [cloud-hosted router](/graphos/routing/cloud/) + +- Learn more about deploying router instances in your own infrastructure in [self-hosted router](/graphos/routing/self-hosted/) + +- Learn the basics about configuring a router in [Configuring a Router](/graphos/routing/configure-your-router) + +- For all available configuration options, go to [Router configuration](/graphos/reference/router/configuration) reference docs + +- To learn more about the intricacies of query plans, see the [example graph](/graphos/reference/federation/query-plans#example-graph) and [query plan](/graphos/reference/federation/query-plans#example-graph) in reference docs + +- For the most performant query planning, configure and use the [Rust-native query planner](/graphos/routing/query-planning/native-query-planner). diff --git a/docs/source/routing/cloud/aws-migration.mdx b/docs/source/routing/cloud/aws-migration.mdx new file mode 100644 index 0000000000..a4e9eadcc3 --- /dev/null +++ b/docs/source/routing/cloud/aws-migration.mdx @@ -0,0 +1,159 @@ +--- +title: Migrate Serverless routers to AWS +subtitle: Learn how to migrate Serverless cloud routers from Fly.io to AWS +description: Migrate your Apollo GraphOS Serverless cloud router to AWS for improved reliability and performance. Learn about changes, migration steps, and who needs to migrate. +noIndex: true +--- + + + +This page only applies to Serverless cloud routers created before May 21, 2024. +All Serverless cloud routers created on or after this date automatically run on AWS. + + + +Serverless is switching cloud providers from Fly.io to AWS to improve reliability and performance. +Serverless cloud routers running on Fly.io infrastructure must be migrated in GraphOS Studio. + +## Who needs to migrate? + +You may need to migrate if: + +- Your organization is on a Serverless plan OR +- Your organization is on a Dedicated plan but uses Serverless variants for non-production environments + +To check if you need to migrate, go to [GraphOS Studio](https://studio.apollographql.com?referrer=docs-content). +If a graph's **Cloud Router Details** on the **Overview** page shows **ord - US (Chicago)** as the **Region**, you need to migrate it. + +Cloud router region showing ord - US (Chicago) in GraphOS Studio + +Cloud routers on Fly.io will continue to operate until June 27, 2024. After this date, any cloud routers on Fly.io will be permanently deleted and graphs using them will no longer respond to requests. +Don't hesitate to contact [cloud@apollographql.com](mailto:cloud@apollographql.com) with any migration questions or concerns. + +## What's changing? + +The move to AWS improves reliability and performance. It also changes the cloud hosting region and inactivity periods. +With improved reliability and performance, Serverless can offer additional GraphOS Router features. Refer to the [pricing page](https://www.apollographql.com/pricing#graphos-router) for the full list of supported features. + +### Reliable throughput + +On AWS, Serverless cloud routers can process a consistent 10 requests per second (RPS) of throughput. + + + +If you need more than 10 RPS throughput or have [complex schemas](/graphos/routing/cloud/serverless/#serverless-compute-limitations), consider upgrading to Dedicated. + + + +### Hosting region + +On Fly.io, cloud routers were hosted in Chicago (ord). On AWS, they're hosted in Northern Virginia (us-east-1). This means faster performance, particularly for customers running subgraph servers on AWS, especially if they are in or near us-east-1. + + + +Dedicated offers a [wider variety of AWS regions](/graphos/routing/cloud/dedicated#runs-on-aws). + + + +### Inactivity periods + +On Fly.io, Serverless cloud routers sleep after two minutes of inactivity. Sleeping routers can't serve requests and must wake up to do so. On AWS, cloud routers sleep after seven days of inactivity. + +After a total 30 days of inactivity, Apollo deletes Serverless cloud routers. +Deletion preserves a cloud router's associated variant's schema but deletes the underlying cloud router. Learn more in [Serverless router status](/graphos/routing/cloud/serverless/#serverless-router-status). + +| | Fly.io Hosted | AWS Hosted | +| -------------------------------------- | ------------- | ---------- | +| Inactivity period
      before sleep | 2 minutes | 7 days | +| Inactivity period
      before deletion | 30 days | 30 days | + +## How to migrate + +Apollo is unable to offer an in-place migration. To migrate, you need to create a new variant on your graph, or create a new graph entirely. Once you create this new variant or graph, you receive a new graph ref and endpoint URL that you must redirect your client traffic to. + + + +To avoid downtime for clients querying your graph, don't delete the variant that houses your existing cloud router until you've created a new one. + + + +### Step 1. Create a new graph + +To get started, create a new graph or variant in GraphOS Studio. See the [getting started](/graphos/quickstart/cloud/#from-an-existing-account) for details on creating a new graph. + + + +**For Dedicated customers with Serverless variants**: + +You can't migrate Serverless variants on a Dedicated plan from Studio. Instead, you must publish a new variant or graph using the [Rover CLI](/rover/commands/subgraphs#publishing-a-subgraph-schema-to-graphos). +All variants created via Rover default to Serverless, even if your organization is on the Dedicated plan. + + + +All Serverless cloud routers created on or after May 21, 2024 automatically run on AWS. +You can confirm your new router is running on AWS by checking that the router region is **AWS us-east-1** on the variant's **Overview** page under **Cloud Router Details**. + +Variant overview page in GraphOS Studio + +Creating a new graph or variant generates a new endpoint URL and graph ref. You'll update these values in later steps. + +### Step 2. Add subgraphs + +Each variant needs at least one subgraph. If you have multiple subgraphs, [add each subgraph](/graphos/quickstart/next-steps/#add-another-subgraph) to your new variant. + +### Step 3. Setup router configuration + +Copy and paste your old router's configuration into your new one. You can access a cloud router's configuration in GraphOS Studio under **Cloud Router > Configuration**. + +Configuring the cloud router in GraphOS Studio + +Router configuration defines important values like CORS policies and header propagation. + + + +If you have [secrets](/graphos/routing/cloud/configuration#managing-secrets) in your old cloud router config, you must also set them in your new one. Secrets can't be read once saved. + + + +### Step 4. Test + +After you've added all your subgraphs and set up your cloud router config, try running a few sample operations from [Explorer](/graphos/platform/explorer/). +You may need to enable [subgraph errors](/graphos/routing/observability/subgraph-error-inclusion) to troubleshoot if your operations don't execute. + +Simulate production traffic before going live. Serverless on AWS offers less but more reliable throughput than on Fly.io. If you exceed throughput limits, your clients receive 429 errors. + + + +It isn't possible to increase throughput on Serverless. If you need more than 10 RPS throughput, consider upgrading to Dedicated. + + + +### Step 5. Go live + +To go live, update the endpoint URL your clients use to query your graph. You can see your new router's endpoint from the **Overview** page of your variant. + +Variant overview page in GraphOS Studio + +If you use any Rover commands in your CI/CD, update the graph ref. + +Once you've updated your client codebase and Rover commands, you can delete the variant housing your Fly.io cloud router. diff --git a/docs/source/routing/cloud/configuration.mdx b/docs/source/routing/cloud/configuration.mdx new file mode 100644 index 0000000000..010ff55b34 --- /dev/null +++ b/docs/source/routing/cloud/configuration.mdx @@ -0,0 +1,373 @@ +--- +title: Cloud Router Configuration +subtitle: Learn how to configure cloud routers in GraphOS Studio +description: Learn about cloud router configurations including HTTP header rules, CORSs settings, secret management, and more in GraphOS Studio. +redirectFrom: + - /graphos/cloud-routing/configuration +--- + +After you create a cloud supergraph, you can manage its router configuration from the **Cloud Router** page in [GraphOS Studio](https://studio.apollographql.com?referrer=docs-content). + +The **General** tab shows the following information: + +- The URL of your router's GraphQL endpoint + - Every cloud router's URL is on a subdomain of `apollographos.net`. +- Your router's current status and [launch history](/graphos/platform/schema-management/delivery/launch) + +From the **Configuration** tab, you can manage the following: + +- [Secrets](#managing-secrets) +- Your router's [YAML-based configuration](#router-configuration-yaml) + +The Cloud Router page in GraphOS Studio + +## Managing secrets + +You can store secret string values that you can then use in your router's [YAML configuration](#router-configuration-yaml). For example, you might store an authorization token that the router needs to include in each of its request to a subgraph. + +To add a new secret, click **Save a secret**. + +In the dialog that appears, enter a name and value for your secret. You can't view a secret's value after you save it, so make sure that the value is correct before saving. When you're ready, click **Save secret**. + +Your secret is encrypted and stored. You can then use the secret's value in your router's YAML configuration. + +The following example YAML configuration uses the value of a secret named `MY_SECRET`: + +```yaml +headers: + all: + request: + - insert: + name: 'subgraph-token' + value: '${env.MY_SECRET}' # highlight-line +``` + +## Router configuration YAML + +You can configure your router's behavior in **Router configuration YAML** on the **Cloud Router** tab or page. + +On the [Serverless plan](https://www.apollographql.com/pricing/), you can configure: + +- [HTTP headers](#http-header-rules) that the router sends to your subgraphs +- [CORS rules](#cors-settings) for browser-based applications connecting to the router +- [Subgraph error inclusion](#subgraph-error-inclusion) to expose subgraph errors to querying clients (including the Apollo Explorer) + +* [Introspection](#introspection) to allow resolving introspection queries. + +[Dedicated and Enterprise plans](https://www.apollographql.com/pricing/) offer a [wider variety of configurations](/graphos/routing/configure-your-router#yaml-file-based-configuration). + +If you require more advanced router customization, get in touch to learn about your about Dedicated and Enterprise plan options. + +### HTTP header rules + +You can configure which HTTP headers your router includes in its requests to each of your subgraphs. You can define per-subgraph header rules, along with rules that apply to all subgraphs. + +You define header rules in your **Router configuration YAML**, like so: + +```yaml +# ...other configuration... +headers: + all: # Header rules for all subgraphs + request: + - propagate: + matching: ^upstream-header-.* + - remove: + named: 'x-legacy-account-id' + subgraphs: + products: # Header rules for just the products subgraph + request: + - insert: + name: 'router-subgraph-name' + value: 'products' +``` + +#### Supported header rules + +Cloud routing supports the following types of header rules: + +##### `propagate` + +Enables you to selectively pass along headers that were included in the client's request to the router. + +You can specify which headers to propagate based on a matching [regular expression pattern](https://docs.rs/regex/latest/regex/): + +```yaml +- propagate: + matching: .* +``` + + + +The router never propagates so-called [hop-by-hop headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers#hop-by-hop_headers), such as `Content-Length`, when propagating by pattern. + + + +Alternatively, you can provide a static string via the `named` option. These `named` configurations have additional flexibility, because they support the following options: + +- `default`: A value to set if no value was sent by the client +- `rename`: Renames the header's key to the provided value + +```yaml +- propagate: + named: 'x-user-id' + default: 'abc123' + rename: 'account-id' +``` + +##### `remove` + +Enables you to selectively remove headers that were included in the client's request to the router. Like [`propagate`](#propagate), this option can match either a static string or a [regular expression](https://docs.rs/regex/latest/regex/). + +```yaml +# Do not send this subgraph the "Cookie" header. +- remove: + named: 'Cookie' +- remove: + # Remove headers that include the legacy 'x-' prefix. + matching: ^x-.*$ +``` + +##### `insert` + +Enables you to add custom headers to requests going to a specific subgraph. These headers are always static strings that originate in the router, instead of originating in the client. + +```yaml +- insert: + name: 'sent-from-our-apollo-router' + value: 'indeed' +``` + +#### Rule ordering + +Header rules are applied in the same order they're declared, and later rules can override the effects of earlier rules. Consider this example: + +

      โŒ

      + +```yaml title="bad_configuration.yaml" +headers: + all: + request: + - remove: + named: 'test' + - propagate: + matching: .* +``` + +In this example, first any header named `test` is removed from the list of headers to propagate. However, the list of headers to propagate is currently empty! Next, the `propagate` rule adds all headers to the propagation list, including `test`. + +To correctly remove a header from the propagation list, make sure to define your `remove` rule after any `propagate` rules: + +

      โœ…

      + +```yaml title="good_configuration.yaml" +headers: + all: + request: + - propagate: + matching: .* + - remove: + named: 'test' +``` + +With this ordering, first all headers are added to the propagation list, then the `test` header is removed. + +#### Example + +Here's a complete example that demonstrates all supported `headers` configuration options: + +```yaml +headers: + # Header rules for all subgraphs + all: + request: + # Propagate matching headers + - propagate: + matching: ^upstream-header-.* + # Propagate matching headers + - propagate: + named: 'some-header' + default: 'default-value' + rename: 'destination-header' + # Remove the "x-legacy-account-id" header + - remove: + named: 'x-legacy-account-id' + # Remove matching headers + - remove: + matching: ^x-deprecated-.* + # Insert the 'my-company' header + - insert: + name: 'my-company' + value: 'acme' + # Subgraph-specific header rules + subgraphs: + products: + request: + # Calls to the products subgraph have the "router-subgraph-name" header set to `products`. + - insert: + name: 'router-subgraph-name' + value: 'products' + accounts: + request: + # Calls to the accounts subgraph have the "router-subgraph-name" header set to `accounts`. + - insert: + name: 'router-subgraph-name' + value: 'accounts' +``` + +### CORS settings + + + +If your router serves exclusively non-browser-based clients, you probably don't need to modify the default CORS configuration. + +For a more general introduction to CORS and common considerations, see the following sections: + +- [Why use CORS?](/apollo-server/security/cors#why-use-cors) +- [Choosing CORS options for your project](/apollo-server/security/cors#choosing-cors-options-for-your-project) + + + +By default, the router enables only GraphOS Studio to initiate browser connections to it. If your supergraph serves data to other browser-based applications, you need to do one of the following in the `cors` section of your **Router configuration YAML**: + +- Add the origins of those web applications to the router's list of allowed `origins`. + - Use this option if there is a known, finite list of web applications that consume your cloud supergraph. +- Add a regular expression that matches the origins of those web applications to the router's list of allowed `origins`. + - This option comes in handy if you want to match origins against a pattern, see the example below that matches subdomains of a specific namespace. +- Enable the `allow_any_origin` option. + + - Use this option if your supergraph is a public API with arbitrarily many web app consumers. + - With this option enabled, the router sends the [wildcard (`*`)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin#directives) value for the `Access-Control-Allow-Origin` header. This enables any website to initiate browser connections to it (but they can't provide cookies or other credentials). + +- You must use the `origins` + `match_origins` option if clients need to [authenticate their requests with cookies](#passing-credentials). + +The following snippet includes an example of each option (use either `allow_any_origin`, or `origins + match_origins`): + +```yaml +cors: + # Set to true to allow any origin + # (Defaults to false) + allow_any_origin: true + + # List of accepted origins + # (Ignored if allow_any_origin is true) + # (Defaults to the GraphOS Studio url: `https://studio.apollographql.com`) + # + # An origin is a combination of scheme, hostname and port. + # It does not have any path section, so no trailing slash. + origins: + - https://www.your-app.example.com + - https://studio.apollographql.com # Keep this so GraphOS Studio can run queries against your router + match_origins: + - 'https://([a-z0-9]+[.])*api[.]example[.]com' # any host that uses https and ends with .api.example.com +``` + +You can also turn off CORS entirely by setting `origins` to an empty list: + +```yml +cors: + origins: [] +``` + +#### Passing credentials + +If your router requires requests to [include a user's credentials](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#requests_with_credentials) (for example, via cookies), you need to modify your CORS configuration to tell the browser those credentials are allowed. + +You can enable credentials with CORS by setting the [`Access-Control-Allow-Credentials`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials) HTTP header to `true`. + + + +Your router must specify individual `origins` to support credentialed requests. If your router enables `allow_any_origin`, your browser will refuse to send credentials. + + + +To allow browsers to pass credentials to your router, set `allow_credentials` to `true`, like so: + +```yaml +cors: + origins: + - https://www.your-app.example.com + - https://studio.apollographql.com + allow_credentials: true +``` + +For examples of sending cookies and authorization headers from Apollo Client, see [Authentication](/react/networking/authentication/). + +#### All `cors` options + +The following snippet shows all CORS configuration defaults for your router: + +```yaml +# +# CORS (Cross Origin Resource Sharing) +# +cors: + # Set to true to allow any origin + allow_any_origin: false + + # List of accepted origins + # (Ignored if allow_any_origin is set to true) + # + # An origin is a combination of scheme, hostname and port. + # It does not have any path section, so no trailing slash. + origins: + - https://studio.apollographql.com # Keep this so GraphOS Studio can still run queries against your router + + # Set to true to add the `Access-Control-Allow-Credentials` header + allow_credentials: false + + # The headers to allow. + # Not setting this mirrors a client's received `access-control-request-headers` + # This is equivalent to allowing any headers, + # except it will also work if allow_credentials is set to true + allow_headers: [] + + # Allowed request methods + methods: + - GET + - POST + - OPTIONS + + # Which response headers are available to scripts running in the + # browser in response to a cross-origin request. + expose_headers: [] +``` + +#### Response `Vary` header + +A plugin may set a response `Vary` header. If, after all plugins are processed, there is no response `Vary` header, then the router will add one with a value of `origin`. + +### Subgraph error inclusion + +By default, your cloud supergraph redacts the details of subgraph errors in its responses to clients. The router instead returns a default error with the following message: + +``` +Subgraph errors redacted +``` + +This redaction prevents potential leaks of sensitive information to clients. + +If you instead want to propagate subgraph errors to clients, you can add the `include_subgraph_errors` key to your router's YAML configuration, like so: + +```yaml +include_subgraph_errors: + all: true # Propagate errors from all subraphs + subgraphs: + products: false # Do not propagate errors from the products subgraph +``` + +Any configuration under the `subgraphs` key takes precedence over configuration under the `all` key. In the example above, subgraph errors are included from all subgraphs except the `products` subgraph. + +### Introspection + +By default, your cloud supergraph does not resolve introspection queries. You can enable introspection like so: + +```yaml +# Do not enable introspection for production workloads! +supergraph: + introspection: true +``` diff --git a/docs/source/routing/cloud/custom-domains.mdx b/docs/source/routing/cloud/custom-domains.mdx new file mode 100644 index 0000000000..64b5613e3f --- /dev/null +++ b/docs/source/routing/cloud/custom-domains.mdx @@ -0,0 +1,72 @@ +--- +title: Custom Domains +subtitle: Use a custom subdomain for your cloud router endpoint +description: Use a custom domain for your cloud router endpoint to minimize client-side changes, use existing security policies, and shield against DDoS attacks. +redirectFrom: + - /graphos/cloud-routing/custom-domains +--- + + + +To interact with your supergraph, clients send requests to your router's endpoint. The _custom domains_ feature lets you replace the default `apollographos.net` router endpoint URL with your own subdomain. + +Custom domains can help to: + +- Minimize client-side changes +- Use your existing CORS policies and security controls +- Protect your cloud routers from DDoS attacks +- Provide TLS termination to your cloud routers + +## How custom domains work + +Custom domains use [CNAME records](https://www.cloudflare.com/learning/dns/dns-records/dns-cname-record/) to point requests made to your subdomain to your `apollographos.net` router endpoint URL. Custom domains run on [Cloudflare's](https://www.cloudflare.com/) global network. + +## Custom domains setup + +Setup includes two steps: + +1. Setting up a CNAME record in your DNS provider. +2. Opening a ticket with Apollo support to enable your CNAME. + + + +Custom domains will be available through self-service in GraphOS Studio later in 2024. In the meantime, you must open a support request to enable your CNAME with Apollo. + + + +### Setup a CNAME + +Create a CNAME record in your DNS provider that points to your Dedicated variant's [existing subdomain](/graphos/routing/cloud/dedicated-quickstart#router-endpoint-url). For example, create a CNAME for `api.mydomain.com` that points to `current--docs-example.apollographos.net`. + +You can find your Dedicated variant's subdomain in [GraphOS Studio](https://studio.apollographql.com?referrer=docs-content) on the **Cloud Router** page under **API Endpoint**. + +A cloud router's endpoint displayed on the Cloud Router page in GraphOS Studio + + + +CNAME records are assigned at the variant level, so you must set up a separate CNAME record for each graph variant that requires a custom domain. + + + +### Using an existing CNAME + +If you already have a CNAME record for the custom domain you want to use, [contact Apollo Support](#open-a-support-ticket) before making any changes. We'll guide you through remapping from a different host to the GraphOS Cloud subdomain. + +### Open a support ticket + +Next, open a support ticket requesting Apollo to enable your new CNAME. +You can open a ticket by emailing [support@apollographql.com](mailto:support@apollographql.com). Your request may take up to two business days to process. Apollo will notify you when your new CNAME is live. + +Your request may take up to two business days to process. Apollo will notify you when your new CNAME is live. + +## Limitations + +The custom domains feature doesn't support the following: + +- [Apex records](https://learn.microsoft.com/en-us/azure/dns/dns-zones-records#record-names) or [A records](https://learn.microsoft.com/en-us/azure/dns/dns-zones-records#record-types) +- Multiple custom domains per variant +- Load balancing traffic across multiple variants diff --git a/docs/source/routing/cloud/dedicated-quickstart.mdx b/docs/source/routing/cloud/dedicated-quickstart.mdx new file mode 100644 index 0000000000..6dafb026ce --- /dev/null +++ b/docs/source/routing/cloud/dedicated-quickstart.mdx @@ -0,0 +1,138 @@ +--- +title: Get Started with Cloud Dedicated +subtitle: Create your first Dedicated cloud router +description: Run a cloud router for your GraphQL APIs on dedicated infrastructure that Apollo provisions and manages. +--- + + + +Follow this hands-on guide to create a new graph that uses a Dedicated cloud router. +To learn about Dedicated cloud routing in general, go to the [Cloud Dedicated overview](/graphos/routing/cloud/dedicated). + +## Prerequisites + +To complete this quickstart, you must have the following: + +- A [GraphOS Studio](https://studio.apollographql.com?referrer=docs-content) account +- An organization with the Dedicated planโ€”get in touch to request access. +- One or more GraphQL APIs that Apollo can access. That means you must either: + - Make your GraphQL API(s) available via a publicly accessible URL, for example, `https://api.mycompany.com/subgraphA` + - Keep your GraphQL API(s) private but allow secure connections, for example, via [VPC networking](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html) + +If you have multiple subgraphs, each needs to be exposed to Apollo. Your supergraph, however, should only be publicly accessible via your cloud router. + + + +In a supergraph, each GraphQL API is called a _subgraph_. Apollo refers to these GraphQL APIs as subgraphs, even if you only connect one GraphQL API. + +The GraphOS Router doesn't supported nested federationโ€”that is, a subgraph cannot act as a supergraph for another set of subgraphs. + + + +## Step 1. Create a new graph + +To provision a new Dedicated cloud router, you must first create a new graph in [GraphOS Studio](https://studio.apollographql.com?referrer=docs-content). To do so, click **Create New Graph** from the **Graphs** tab. + +Graphs tab in GraphOS Studio + +## Step 2. Connect APIs + +1. Next, connect your GraphQL API to Apollo. + + - If your API URL is publicly accessible, enter the API URL. This URL is the URL that client applications currently use to query your API. + - If your API isn't publicly accessible and requires private networking, you can connect to it with [AWS VPC Lattice](/graphos/routing/cloud/lattice-configuration). Select **My endpoint isn't publicly accessible** to connect a VPC. Follow the prompts to complete private subgraph setup. + +2. Enter a **Subgraph name**. The name should reflect your API's data or capabilities and uniquely identify your API among any other APIs you might add to the supergraph later. + + + + The subgraph name is immutable. + + + +3. Select the backend **provider** and **region** to deploy your cloud router in. +4. Optionally, configure headers, secrets, CORS rules, or other configurations. You can always [update your router configuration](#step-3-inspect-and-configure-your-cloud-router) as needed. +5. Provide a **Supergraph name** and **ID**. + + - The supergraph name is displayed throughout Studio and helps your team distinguish between your graphs. You can change your graph's name at any time. + - The ID is immutable and must be unique across all of Apollo. Ensure it starts with a letter and contains only letters, numbers, and dashes. You'll use the ID to reference your graph from various tools, such as the Rover CLI. + +6. Click **Create GraphOS Router**. + +Provisioning a router for your new supergraph may take a few moments. Once done, click **Query your supergraph** to open the Explorer and begin playing with your graph, or **Open README** to go to your graph's landing page. + +Before moving to the next step, add any other GraphQL APIs you want to connect. Open the **Subgraphs** page from the left navigation and click **Add a subgraph**. + +The 'Add a subgraph' button in the subgraphs page in GraphOS Studio + +Every router configuration or supergraph schema changeโ€”including adding a subgraphโ€”triggers a new [launch](/graphos/delivery/launches/). Every launch automatically deploys new cloud router instances for your supergraph. + + + +The launch process typically takes 1-2 minutes but may take up to 5 minutes. During the process, Apollo provisions new GCUs and swaps them in once they're online. Deployments minimize API degradation and downtime. + + + +## Step 3. Inspect and configure your cloud router + +Dedicated cloud routers have a separate UI for management and configuration. Open the **Cloud Router** page from the left navigation. This page shows a summary of your cloud router, including its **API endpoint** and **API details**. + +Use the **Configuration** tab to manage your cloud router's configuration, including **Secrets** and **Router configuration YAML**. See the [router docs](/router/configuration/overview) for more information. + +The Cloud Router page in GraphOS Studio + +## Step 4. Test and validate + +To test whether your graph works as intended, run a sample query by clicking **Run in Explorer** from your graph's **README** page. + +[Enable subgraph error reporting](/graphos/routing/cloud/lattice-troubleshooting/#enable-subgraph-error-inclusion) if you run into issues. + +For further testing, you can add variants to your graph for development or staging environments. To do so, go to **Settings** > **This Graph** > **Variants** and click **Add a variant**. + +Apollo recommends running a [load test](/graphos/routing/cloud/throughput-guide#load-testing) to determine how much [throughput capacity](/graphos/routing/cloud/throughput-guide) you need to run your graph. + +## Step 5. Go live + +Your supergraph is ready to start receiving client operations! If you have existing client applications that connect directly to your GraphQL API, you can update their GraphQL endpoint URL to your router's URL. + +Similarly, any new client applications should use your router's URL. + + + +- For all browser-based clients, make sure their origin is allowed in your router's [CORS rules](#cors-rules). + +- Only update clients that communicate with the correct instance of your GraphQL API. For example, if your API has staging and production instances, only update clients that communicate with the instance used by this supergraph variant. + + + +#### Router endpoint URL + +You can find your endpoint URL on the **Cloud router** page in GraphOS Studio. + +A cloud router's endpoint displayed on the Cloud Router page in GraphOS Studio + + + +By default, cloud router URLs are on a subdomain of `apollographos.net`. You can setup a [custom domain](/graphos/routing/cloud/custom-domains) to minimize client-side changes. + + + +## Next steps + +Congratulations! ๐ŸŽ‰ You've built a cloud supergraph on GraphOS. Check out the general Quickstart's [Next steps](/graphos/get-started/guides/quickstart#next-steps) for some of the most common and important features to learn about. diff --git a/docs/source/routing/cloud/dedicated.mdx b/docs/source/routing/cloud/dedicated.mdx new file mode 100644 index 0000000000..b07c8673df --- /dev/null +++ b/docs/source/routing/cloud/dedicated.mdx @@ -0,0 +1,52 @@ +--- +title: Cloud Dedicated Overview +subtitle: Learn about the Dedicated cloud router offering and pricing +description: Learn about Apollo's dedicated cloud routing for GraphQL APIs including available AWS regions and pricing. +--- + + + +GraphOS _Cloud Dedicated_ is the Apollo offering that lets you run a cloud router on dedicated, pre-provisioned infrastructure that you control and scale. It gives you access to a fully managed and monitored fleet of GraphOS Routers. + +The Cloud Dedicated approach lets you implement and scale your supergraph without managing any additional infrastructure. Tailored for teams handling production-grade workloads, Cloud Dedicated offers additional control over performance and security. + + + +Go the [Cloud Dedicated quickstart](/graphos/routing/cloud/dedicated-quickstart) to get started. + + + +## Runs on AWS + +Cloud Dedicated runs a fleet of GraphOS Routers in the AWS region of your choice. The following regions are currently available: + +- us-east-1 +- us-east-2 +- us-west-2 +- ap-southeast-1 +- ap-southeast-2 +- ap-northeast-1 +- ca-central-1 +- eu-central-1 +- eu-west-1 +- eu-west-2 +- eu-north-1 + +Dedicated supports subgraphs running in any cloud region or provider. However, you may incur additional networking charges for subgraphs running outside your selected AWS region. AWS VPC Lattice is only supported for the regions listed above. + +## Pricing + +Cloud Dedicated pricing is based on the amount of _Graph Compute Units_ (GCUs) needed to run your graph. A GCU is a unit of throughput capacity. You can scale GCUs via [GraphOS Studio](https://studio.apollographql.com?referrer=docs-content) or the [GraphOS Platform API](/graphos/reference/platform-api/). + +To learn about GCU performance and scaling, consult the [Throughput guide](/graphos/routing/cloud/throughput-guide). + +## Private preview + +Cloud Dedicated is a new product and is in [preview](/graphos/reference/feature-launch-stages/#preview) while it matures. It is only available to select customers on an invite-only basis. If you have feedback or are interested in joining the preview, get in touch. + +Please note the following while Cloud Dedicated is in preview: + +- 99.9% SLA for ingress traffic +- Limited to customers running subgraphs in AWS +- Month-to-month billing, pricing subject to change +- Limited scaling, up to 10 GCUs per variant diff --git a/docs/source/routing/cloud/index.mdx b/docs/source/routing/cloud/index.mdx new file mode 100644 index 0000000000..0d6111cf8f --- /dev/null +++ b/docs/source/routing/cloud/index.mdx @@ -0,0 +1,166 @@ +--- +title: Cloud Routing +subtitle: Cloud-hosted routers for cloud supergraphs +--- + + + +Apollo has paused new sign-ups for Serverless and Dedicated plans while we improve our offerings based on user feedback. This means cloud routing is temporarily unavailable to new users. In the meantime, you can explore other GraphOS features with a [free trial](https://studio.apollographql.com/signup?referrer=docs-content). + + + +When you create a cloud supergraph, GraphOS provisions and manages a _cloud router_. Routers act as entry points to your GraphQL APIs. Individual GraphQL APIs are called _subgraphs_ in this architecture. + +```mermaid +flowchart LR; + clients(Clients); + subgraph "GraphOS Cloud" + router(["Cloud router"]); + end; + subgraph YourInfra["Your infrastructure"]; + subgraphA[Subgraph A]; + subgraphB[Subgraph B]; + end; + clients -.- router; + router --- subgraphA & subgraphB; + classDef padding padding-left:1em, padding-right:1em + YourInfra:::padding + class clients secondary; +``` + +Clients send operations to your router's public endpoint instead of your subgraphs. + +GraphOS only hosts the runtime for your supergraph's cloud router. GraphQL servers for your subgraphs are still hosted in your infrastructure. + +

      + + Create your first cloud supergraph + +

      + +## Federation and subgraph compatibility + +Cloud supergraphs use [Apollo Federation 2](/federation/) for their core architecture. [Many GraphQL server libraries](/graphos/reference/federation/compatible-subgraphs) support Federation 2. Your GraphQL API doesn't already need to be using Apollo Federation to add it to a cloud supergraph. + +## Cloud router types and availability + +Cloud supergraphs are only available to organizations with Serverless and Dedicated plans**. +Serverless cloud routers run on shared infrastructure. Dedicated cloud routers run on dedicated infrastructure that you control and scale. +Cloud routers aren't available with Enterprise or legacy Free or Team plans. + + + +**We've paused new sign-ups for Serverless and Dedicated plans while we improve our offerings based on user feedback. In the meantime, you can explore GraphOS features with a [free trial](https://studio.apollographql.com/signup?referrer=docs-content). + + + +## Cloud router regions + +Serverless cloud routers are hosted in the us-east-1 AWS region. Dedicated cloud routers have a wider [variety of options](/graphos/routing/cloud/dedicated/#runs-on-aws). Region selection for cloud routers is only available on the Dedicated plan. Contact Sales to learn more. +You can view a cloud router's region on its graph's **Overview** page under **Cloud Router Details**. + +Variant overview page in GraphOS Studio + +## Cloud router status + +Cloud routers can have the following statuses: + +| Status | Description | +| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Initializing** | Your cloud router is being created. This process may take up to five minutes. [Learn more.](#initializing) | +| **Running** | Your graph is operating normally. | +| **Error** | Your cloud router is running, but a deployment recently failed. For more information on the failure, see the **Launches** page in GraphOS Studio. | + + + +Serverless routers have additional statuses, including **Sleeping** and **Deleted**. Learn more on the [Serverless overview page](/graphos/routing/cloud/serverless/#serverless-router-status). + + + +You can see your cloud router's status in GraphOS Studio on the associated graph's **Overview** page under **Cloud Router Details**. + +### Initializing + +Apollo provisions a router whenever you create a cloud supergraph in GraphOS Studio or whenever you create a new variant for an existing cloud supergraph. Each variant has its own distinct router. + +When you first create a variant, the router provisioning process can take a few minutes. While this process completes, an **INITIATING ENDPOINT** label appears at the top of the variant's page in Studio: + +Label in Studio indicating a router hasn't finished provisioning + +Once initialized, you can [configure your cloud router](/graphos/routing/cloud/configuration). + +## Cloud launches + +Publishing a new subgraph schema or editing a cloud router's config triggers a new [launch](/graphos/delivery/launches/). Every launch automatically deploys new router instances for your graph. You can see a launch's details, including possible failures, from a graph's **Launches** page in GraphOS Studio. + + + +A router deployment might fail due to a platform incident or schema composition issues. To resolve this, try republishing your subgraph schema. + + + +## Router version updates + +Apollo manages the Apollo Router Core version deployed to cloud routers. It ensures that newly released versions are deployed within 30 days of release. Some minor and patch versions may be skipped. + +Router releases go through rigorous testing before deployment on GraphOS Cloud. An Apollo engineer oversees deployment. If any cloud routers fail to boot up, they roll back to a previous version. While some edge cases may ariseโ€”for example, a query planner update could result in slightly degraded performanceโ€”router updates should not disrupt your supergraphs. + + + +Opting out of router updates to cloud routers isn't currently supported. + + + +## Security and compliance + +The entire GraphOS platform, including its cloud routing infrastructure, is SOC 2 Type 2 certified. +Secrets are encrypted both in transit and at rest. +Secrets are only available inside the runtime environment. You have total control over when those secrets are resolved in configuration. + +The Apollo Router Core (the underlying technology for cloud routing) has been [tested and audited by Doyensec](https://doyensec.com/resources/Doyensec_Apollo_Report_Q22022_v4_AfterRetest.pdf). + +### GraphOS Cloud on AWS + +GraphOS Cloud on AWS is a managed API solution. It runs the GraphOS Router on AWS infrastructure to provide a high-performance, configurable GraphQL router. + +[Download an overview of GraphOS Cloud on AWS security and compliance practices](https://www.apollographql.com/trust/request-security-report). +For more information on Apollo's compliance and security measures, visit the [Trust Center](https://www.apollographql.com/trust/compliance-and-security). + +### Which types of data are collected by a cloud supergraph? + +A cloud supergraph uses a GraphOS Router to execute operations across one or more subgraphs hosted in your infrastructure: + +```mermaid +flowchart LR; + clients(Clients); + subgraph "GraphOS"; + router(["Router"]); + end; + subgraph "Your infrastructure"; + subgraphA[Subgraph A]; + subgraphB[Subgraph B] + router --- subgraphA + router --- subgraphB + end; + clients -.- router; + class clients secondary; +``` + +Each instance of GraphOS Router runs in its own managed container. These instances use the same mechanisms to report operation metrics to GraphOS as a GraphOS Router or Apollo Router Core instance running in any other environment. The only difference is that metrics reporting is always enabled for a cloud supergraph's router. + +GraphOS Routers do not persist or log any response data returned by your subgraphs. They only assemble this data into responses for requesting clients. diff --git a/docs/source/routing/cloud/lattice-configuration.mdx b/docs/source/routing/cloud/lattice-configuration.mdx new file mode 100644 index 0000000000..bbd0a32dc8 --- /dev/null +++ b/docs/source/routing/cloud/lattice-configuration.mdx @@ -0,0 +1,348 @@ +--- +title: Amazon VPC Lattice Configuration +subtitle: Securely communicate with subgraphs on your Amazon VPC +description: Configure Amazon VPC Lattice to send traffic to and receive traffic from your Apollo GraphOS cloud router. +redirectFrom: + - /graphos/cloud-routing/lattice +--- + + + +Cloud Dedicated uses [Amazon VPC Lattice](https://aws.amazon.com/vpc/lattice/) to send traffic to subgraphs running in an Amazon VPC without exposing them to the internet. + +```mermaid +flowchart LR; + clients(Clients); + subgraph "Apollo Cloud"; + router(["Cloud
      router"]); + end; + subgraph "Amazon Virtual Private Cloud" + lattice[Amazon VPC
      Lattice service] + service1[Subgraph 1]; + service2[Subgraph 2]; + service3[Subgraph 3]; + end; + + router --> lattice + lattice --> service1 & service2 & service3; + + clients -->|Requests| router; +``` + +This guide shows how to create Lattice services and share them with GraphOS. This configuration lets your GraphOS cloud routers securely communicate with your private subgraphs. + + + +Using Amazon VPC Lattice incurs costs outside of your GraphOS Dedicated spend. Refer to the [Lattice pricing page](https://aws.amazon.com/vpc/lattice/pricing/) to learn more. + + + + +## How GraphOS ensures subgraph security through Lattice + +When you first share Lattice services with GraphOS, it scans the Lattice services to retrieve their ARNs and domain names. +Then, when you add a private subgraph to a cloud supergraph, GraphOS checks that the subgraph's domain matches one of the Lattice services associated with your GraphOS organization. + +As a second line of defense, supergraphs use AWS IAM permissions and SigV4 to only allow traffic to subgraphs in the same GraphOS organization. + +## Configuration overview + +To allow GraphOS cloud routers to send traffic to private subgraphs in an Amazon VPC, you must: + +1. Create a Lattice target group for each subgraph hosted in your Amazon VPC. +2. Create a Lattice service for each graph variant in GraphOS. +3. Share your Lattice service(s) with the Apollo AWS Organization via a resource share. +4. Link the resource share in GraphOS Studio. + +This guide offers instructions for each step. + +You can also use the [Apollo Terraform module](https://github.com/apollographql/terraform-graphos-aws) to provision Lattice target groups, services, and resource shares. +The module completes steps 1 - 3 of this configuration guide. Once you've set it up, you can skip to [step 4](#step-4-link-resource-share)โ€”linking the provisioned resource share in GraphOS Studio. +Refer to the [module's README](https://github.com/apollographql/terraform-graphos-aws#apollo-graphos-cloud-private-subgraphs-module) for more information. + + + +- You can use Amazon VPC Lattice in your organization for other uses than routing GraphOS traffic to subgraphs. A Lattice service can be associated with multiple service networks, and GraphOS associates your Lattice services with its own service network. +- You can only use Lattice for subgraphs in the same AWS region as your cloud router. If you need to run subgraphs in different AWS regions or run your workloads in a region not yet supported by Dedicated, please get in touch. + + + +## Step 1. Create a target group + +A VPC Lattice _target group_ is a collection of targets, or compute resources, that run your application or service. +In the GraphOS context, a target group maps to a subgraph. +If you have multiple subgraphs, repeat these steps for each subgraph. + + +1. In the AWS Console for your region of choice, go to the VPC service page: + +- [US East (N. Virginia) - us-east-1](https://us-east-1.console.aws.amazon.com/vpc/home?region=us-east-1) +- [Europe (Ireland) - eu-west-1](https://eu-west-1.console.aws.amazon.com/vpc/home?region=eu-west-1) + +2. In the left navigation, scroll down and open **VPC Lattice > Target groups**. +3. Click **Create target group** on the top right. +4. In the **Basic configuration** section, set the properties that match your subgraph resources. + + Amazon VPC service page + +5. (Optional) If you use a target type with health checks, ensure you configure your health checks. Otherwise, Lattice can't send traffic to your subgraphs. +6. Register the targets based on your chosen target type. For example, if you selected **IP addresses** as your target type, add each IP address. + + Amazon VPC service page + +7. Review your targets to make sure all information is correct. +8. Click **Create target group** at the bottom right corner of the page. + +Congratulations! You've created an Amazon VPC Lattice target group. +Repeat this process for each subgraph you want to share with GraphOS. + +## Step 2. Create a Lattice service + +In Lattice, a _service_ represents a self-contained software module. +A VPC Lattice service has a listener that uses rules, called listener rules, that you can configure to help route traffic to your targets. +In this step, you create a single VPC Lattice service with listener rules for each of your target groups. + +In the GraphOS context, a Lattice service maps to a graph variant. +Create one service for each of your variants. + +1. In the AWS Console for your region, go to the VPC service page: + +- [US East (N. Virginia) - us-east-1](https://us-east-1.console.aws.amazon.com/vpc/home?region=us-east-1) +- [Europe (Ireland) - eu-west-1](https://eu-west-1.console.aws.amazon.com/vpc/home?region=eu-west-1) + +2. In the left navigation, scroll down and open **VPC Lattice > Services**. +3. Click **Create service** in the top right. +4. In the **Identifiers** section, enter a descriptive name for the service. Optionally, enter a description and tags. + + Amazon VPC service page + +5. In the **Custom domain configuration** section, leave **Specify a custom domain configuration** unchecked. +6. In the **Service access** section, select the **AWS IAM** authentication type and paste the following authorization policy. This policy ensures that only the Apollo AWS Organization can send traffic to your subgraphs. + + ```json showLineNumbers=false + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": "*", + "Action": "vpc-lattice-svcs:Invoke", + "Resource": "*", + "Condition": { + "ForAnyValue:StringLike": { + "aws:PrincipalOrgPaths": "o-9vaxczew6u/*/ou-leyb-l9pccq2t/ou-leyb-fvqz35yo/*" + } + } + } + ] + } + ``` + +7. (Optional) For extra security, you can audit all the traffic coming to your subgraph by enabling **Access logs** in the **Monitoring** section. +8. Once you've configured the service, click **Next** on the bottom right of the page. +9. Define routing information to the target group you created in [Step 1](#step-1-create-lattice-target-group). Set the protocol to **HTTPS** and the port to **443**. + + + + For security reasons, Apollo requires you to use HTTPS for your listener. Using HTTPS enforces encryption in transit of the traffic between your GraphOS cloud router and your Lattice service. + + + + Amazon VPC service page + +10. If you have multiple target groups, add a **Listener rule** for each target group. + + Amazon VPC service page + +11. Click **Next** at the bottom right of the page once you've configured your listener. +12. Don't select a VPC Lattice service network. Your subgraphs will integrate with a service network managed by Apollo. Instead, click the **Next** button at the bottom right of the page. +13. Ensure the information you've entered is correct. Then click **Create VPC Lattice service** at the bottom right of the page. + +Congratulations! You've now created a Lattice service with listeners for your subgraphs. + +## Step 3. Share Lattice service + +For GraphOS to access your Lattice service, you must share it with the Apollo AWS organization. +You do this through a _resource share_ in AWS Resource Access Manager (AWS RAM). +A resource share specifies the resources to share and the consumers with whom to share them. + +```mermaid +flowchart LR; + apollo(Apollo Cloud) + subgraph "Amazon Virtual Private Cloud" + lattice[Amazon VPC
      Lattice service] + service1[Subgraph 1]; + service2[Subgraph 2]; + service3[Subgraph 3]; + end; + + apollo-. AWS RAM
      resource share .- lattice + lattice --> service1 & service2 & service3; +``` + +If you have multiple Lattice services, you can share them all through one resource share. + +1. In the AWS Console for your region of choice, go to the Resource Access Manager service page: + +- [US East (N. Virginia) - us-east-1](https://us-east-1.console.aws.amazon.com/ram/home?region=us-east-1) +- [Europe (Ireland) - eu-west-1](https://eu-west-1.console.aws.amazon.com/ram/home?region=eu-west-1) + +2. In the left navigation, scroll down and open **Shared by me > Resource shares**. +3. Click **Create resource share** in the top right corner. +4. In the **Resource share name** section, enter a name for your resource share. +5. In the **Resources section**, select the **VPC Lattice Services** resource type. +6. Select all the Lattice services that contain subgraphs. + + Amazon VPC shared resources page + +7. (Optional) Set tags for your resource share. +8. Click the **Next** button at the bottom right corner of the page. +9. Verify that the **Managed permissions** give access to associate the Lattice services with a service network (`vpc-lattice:CreateServiceNetworkServiceAssociation` and `vpc-lattice:GetService`). Then click the **Next** button at the bottom right of the page. + + Amazon VPC shared resources page + +10. In the **Principals** section, select **Allow sharing with anyone** with a **principal type** of `AWS account`. Enter the following value for the account ID: `282421723282`, then click the **Add** button. + + Amazon VPC shared resources page + +11. Confirm that `282421723282` is the only selected principal for this resource share, then click the **Next** button on the bottom right corner. +12. Confirm that all the information is correct, then click **Create resource share** at the bottom right of the page. + +Congratulations! You've now shared your Lattice service(s) with Apollo's AWS organization. + +The last step is associating your resource share with a graph in GraphOS. + + + +- You have 12 hours to associate your resource share. Otherwise, AWS RAM will fail to process the invitation, and you must restart this step. +- For security purposes, we recommend you continue to the next step immediately after creating the resource share. If you see that the resource share was **Accepted** or **Failed** in the AWS console and you didn't follow [step 4](#step-4-link-resource-share) of this guide, follow the steps to [remove access to private subgraphs](/graphos/routing/cloud/lattice-management#remove-access) and restart this step. + + + +## Step 4. Link resource share + +At this point, you've shared your Lattice service(s) with the Apollo AWS organization. In this step, you link each service to a particular cloud router in GraphOS Studio. +The cloud router can then route client requests. + +```mermaid +flowchart LR; + clients(Clients); + subgraph "Apollo Cloud"; + router(["Cloud
      router"]); + end; + subgraph "Amazon Virtual Private Cloud" + lattice[Amazon VPC
      Lattice service] + service1[Subgraph 1]; + service2[Subgraph 2]; + service3[Subgraph 3]; + end; + + router --> lattice + lattice --> service1 & service2 & service3; + + clients -->|Requests| router; +``` + +1. In the AWS Console for your region of choice, go to the Resource Access Manager service page: + +- [US East (N. Virginia) - us-east-1](https://us-east-1.console.aws.amazon.com/ram/home?region=us-east-1) +- [Europe (Ireland) - eu-west-1](https://eu-west-1.console.aws.amazon.com/ram/home?region=eu-west-1) + +2. In the left navigation, scroll down and open **Shared by me > Resource shares**. +3. Click the resource share you created in the previous step. +4. Copy the **ARN** for the resource share. + + Amazon VPC resource share page + +The next steps differ depending on whether you're creating a [new graph](#setup-for-new-graphs) in GraphOS or adding this [service to an existing graph](#setup-for-existing-graphs). + +### Setup for new graphs + +1. Go to [GraphOS Studio](https://studio.apollographql.com?referrer=docs-content). +2. Click the **Create New Graph** tab at the top right of the screen. +3. Follow Studio's onboarding steps to create a graph with a new private subgraph. +4. When prompted to **Provide your GraphQL API endpoint**, select **My endpoint is not directly accessible** at the bottom of the page. +5. Choose the backend provider you want to use for your private subgraph and the region where your subgraph should be provisioned. + + + + All private subgraphs connected to a GraphOS cloud router must be in the same region. + + + +6. Paste the ARN of the resource share you created and copied from your AWS Console, then click **Link my Resource** and **Next** to continue. +7. From the dropdown menu, select the Lattice service that you want to connect to your GraphOS router. The URL automatically appends a default path of `/api/graphql`, but you can change this path if you want to. +8. Add a **Service Name** to describe your Lattice service. GraphOS Studio uses this name to identify your Lattice service. +9. Paste the GraphQL schema for this subgraph in the **Schema** field. You can also upload a schema file by clicking the **Upload Schema** button. + + + +When your AWS resource is set to private, it isn't accessible by external services by default. This ensures a high level of security for your data, but it also means extra steps are needed to enable communication between your resource and our system. GraphOS needs your GraphQL API's schema so it can generate the correct queries and mutations to send to your subgraph. + + + +10. Update the ID and the name of the supergraph that you want to add this private subgraph to. An ID and name are automatically generated based on your GraphOS organization's name, but you can change both as needed. +11. To finish, click **Create GraphOS Router**. + +Congratulations! You've now created a GraphOS cloud router with a private subgraph. + +### Setup for existing graphs + +1. Go to the graph you want to connect in [GraphOS Studio](https://studio.apollographql.com?referrer=docs-content). +2. From the left sidebar, open the **Subgraphs** tab of your graph. +3. Click **Add a Subgraph** on the right of the page. +4. In the dialog, select the **Private** option, then select the AWS service you want to add from the dropdown menu. The URL automatically appends a default path of `/api/graphql`, but you can change this path if you want to. +5. Add a **Service Name** to describe your Lattice service. GraphOS Studio uses this name to identify your Lattice service. +6. Paste the GraphQL schema for this subgraph in the **Schema** field. You can also upload a schema file by clicking the **Upload Schema** button. + + + +When your AWS resource is set to private, it isn't accessible by external services by default. This ensures a high level of security for your data, but it also means extra steps are needed to enable communication between your resource and our system. GraphOS needs your GraphQL API's schema so it can generate the correct queries and mutations to send to your subgraph. + + + +7. To finish, click **Add Subgraph**. + +Congratulations! You've now added a private subgraph to your GraphOS cloud router. + +## Next steps + +After you've linked your VPC Lattice services with your cloud router, you may want to set up monitoring. +The [Lattice management page](/graphos/routing/cloud/lattice-management) provides information on monitoring and how to further restrict and remove access to subgraphs. +See the [troubleshooting guide](/graphos/routing/cloud/lattice-troubleshooting) if you're having issues with your Lattice setup. \ No newline at end of file diff --git a/docs/source/routing/cloud/lattice-management.mdx b/docs/source/routing/cloud/lattice-management.mdx new file mode 100644 index 0000000000..86c577a401 --- /dev/null +++ b/docs/source/routing/cloud/lattice-management.mdx @@ -0,0 +1,181 @@ +--- +title: Amazon VPC Lattice Management +subtitle: Monitor, restrict, and remove access to subgraphs +description: Manage your Apollo GraphOS cloud router with Amazon VPC Lattice to monitor, restrict, and remove access to subgraphs. +redirectFrom: + - /graphos/cloud-routing/lattice-management +--- + + + +This guide covers: + +- How to monitor traffic flowing through Amazon VPC Lattice to your subgraphs. +- How to add access restrictions to your subgraphs +- How to remove GraphOS access to your subgraphs + + + +If you haven't configured Amazon VPC Lattice yet or need to add new subgraphs, follow the [configuration guide](/graphos/routing/cloud/lattice-configuration). + + + +## Amazon VPC Lattice monitoring + +To confirm that traffic is flowing to your private subgraphs, you can use the metrics and access logs emitted by Amazon VPC Lattice: + +1. In the AWS Console for your region of choice, go to the VPC service page. +2. In the left navigation, scroll down and open **VPC Lattice > Services**. +3. Click the Lattice service used by the subgraph in question. +4. Click the **Monitoring** tab. + +From there, you can configure and enable access logs for your Amazon VPC Lattice service. + +Amazon VPC Lattice access logs + +Use the **Metrics** tab to get a quick overview of traffic flowing to your private subgraphs. + +Amazon VPC Lattice metrics + +You can also use [Amazon CloudWatch metrics emitted by Amazon VPC Lattice](https://docs.aws.amazon.com/vpc-lattice/latest/ug/monitoring-cloudwatch.html) to set up dashboards and alarms to understand the health of your private subgraphs. + +## Further restrict access + +Once you configure an Amazon VPC Lattice service to accept traffic from GraphOS, it's protected by multiple security layers: + +- The Amazon VPC Lattice service network only allows traffic with a valid signature over HTTPS. +- The Lattice service's configured authorization policy allows traffic only from Apollo AWS accounts. (This is the authorization policy you configured in step 6 [when creating your Lattice service](/graphos/routing/cloud/lattice-configuration#step-2-create-a-lattice-service).) +- GraphOS cloud router provisioning compares subgraphs in a supergraph's configuration against the list of known private subgraphs in its Apollo account. It refuses to create or update cloud routers with unknown private subgraphs. +- Cloud routers can only invoke private subgraphs listed in their supergraph configuration. + +You can further restrict access to your private subgraphs by configuring additional [conditions](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html) in your service's authorization policy. +Specifically, you can add conditions to restrict traffic based on your organization's Apollo account ID or your supergraph's graph ref. + +### Update Lattice service authorization policy + +To update a Lattice service's authorization policy, you first need the **Apollo account ID** and/or **graph ref** to which you want to restrict subgraph access. + +#### Get account ID and graph ref + +- Reach out to your Apollo contact to get your account ID. Specify that you need the account ID to update your Lattice service's authorization policy. + + + + The Apollo account ID you specify in your authorization policy isn't the GraphOS organization ID you can find in GraphOS Studio. + + + +- You can find your supergraph's graph ref in your Apollo account: + - Log in to [GraphOS Studio](https://studio.apollographql.com?referrer=docs-content). + - Click on a graph variant on the **Graphs** page. The graph ref is at the top of the page. + +If you want to provide subgraph access to multiple supergraphs or GraphOS accounts, specify multiple graph refs and account IDs when updating your policy. + +#### Update policy + +If you are using the [Apollo Terraform module](https://github.com/apollographql/terraform-graphos-aws), you can set the [`apollo_account_ids` and `apollo_graph_refs` variables](https://github.com/apollographql/terraform-graphos-aws#usage) to update your authorization policy. Provide one or more Apollo account IDs or graph refs: + +```txt showLineNumbers=false disableCopy=true +apollo_account_ids = ["my_account_id", "another_account_id"] +apollo_graph_refs = ["my-graph@my-variant", "another-graph@my-variant"] +``` + +If you aren't using the Apollo Terraform module, follow these steps: + +1. In the AWS Console for your region of choice, go to the VPC service page: + +- [US East (N. Virginia) - us-east-1](https://us-east-1.console.aws.amazon.com/ram/home?region=us-east-1) +- [Europe (Ireland) - eu-west-1](https://eu-west-1.console.aws.amazon.com/ram/home?region=eu-west-1) + +2. In the left navigation, scroll down and open **Services** in the **VPC Lattice** section. +3. Click the Lattice service whose authorization policy you want to configure. +4. In the **Service access** section, update your authorization policy. You can use the following as an example—make sure to replace the account ID and graph ref with your own. + +```json {13-17} showLineNumbers=false +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": "*", + "Action": "vpc-lattice-svcs:Invoke", + "Resource": "*", + "Condition": { + "ForAnyValue:StringLike": { + "aws:PrincipalOrgPaths": "o-9vaxczew6u/*/ou-leyb-l9pccq2t/ou-leyb-fvqz35yo/*" + }, + // Restrict traffic based on Apollo account IDs or graphRefs + "StringEquals": { + "aws:PrincipalTag/Apollo:accountId": "my_account_id_xezf34", + "aws:PrincipalTag/Apollo:graphRef": "my-graph@my-variant" + } + } + } + ] +} +``` + +If multiple supergraphs should have access to the subgraph, use a comma-separated string of graph refs for `aws:PrincipalTag/Apollo:graphRef`. For example: + +```json showLineNumbers=false disableCopy=true +"aws:PrincipalTag/Apollo:graphRef": "my-graph@my-variant, my-graph@another-variant, another-graph@another-variant" +``` + +Similarly, you can use a comma-separated string of account IDs for `aws:PrincipalTag/Apollo:accountId`: + +```json showLineNumbers=false disableCopy=true +"aws:PrincipalTag/Apollo:accountId": "my_account_id_xezf34", "my_account_id_dehs56" +``` + +## Remove access + +To remove GraphOS access to private subgraphs, you must remove both resource shares and service network associations. +Keep in mind that any existing supergraphs that send traffic to your private subgraphs will stop working once you remove access. + +### Remove resource shares + +1. In the AWS Console for your region of choice, go to the Resource Access Manager service page: + +- [US East (N. Virginia) - us-east-1](https://us-east-1.console.aws.amazon.com/ram/home?region=us-east-1) +- [Europe (Ireland) - eu-west-1](https://eu-west-1.console.aws.amazon.com/ram/home?region=eu-west-1) + +2. In the left navigation, click **Resource shares** in the **Shared by me** section. +3. Select the resource share(s) associated with the Apollo AWS organization. Then click the **Delete** button in the top right corner. +4. Click **Delete** in the dialog that appears. + +### Remove service network associations + +1. In the AWS Console for your region of choice, go to the VPC service page: + +- [US East (N. Virginia) - us-east-1](https://us-east-1.console.aws.amazon.com/ram/home?region=us-east-1) +- [Europe (Ireland) - eu-west-1](https://eu-west-1.console.aws.amazon.com/ram/home?region=eu-west-1) + +2. In the left navigation, scroll down and open **Services** in the **VPC Lattice** section. +3. Click the Lattice service you want to disconnect. +4. In the **Service network associations**, select the **graphos-cloud** service name. + +Amazon VPC service page + +5. Click the **Actions** button in the top right of that section. Then, click **Delete network associations**. + +Amazon VPC service page + +6. Follow the confirmation instructions and click **Delete**. + +Deleting the network association can take a few seconds. Once you delete the network association, GraphOS can no longer contact your subgraphs. diff --git a/docs/source/routing/cloud/lattice-troubleshooting.mdx b/docs/source/routing/cloud/lattice-troubleshooting.mdx new file mode 100644 index 0000000000..89f8127c5d --- /dev/null +++ b/docs/source/routing/cloud/lattice-troubleshooting.mdx @@ -0,0 +1,135 @@ +--- +title: Lattice Troubleshooting Guide +subtitle: Troubleshoot common issues and errors with Amazon VPC Lattice +description: Troubleshoot common issues and errors with Amazon VPC Lattice and an Apollo Cloud Dedicated router +redirectFrom: + - /graphos/cloud-routing/lattice-troubleshooting +--- + + + +Refer to the [configuration page](/graphos/routing/cloud/lattice-configuration) to learn how to configure AWS VPC Lattice to send traffic to your subgraphs. + +## Enable subgraph error inclusion + +To help resolve AWS VPC Lattice connection issues, enable subgraph error inclusions for your graph variant. This configuration lets you see error messages generated by your subgraphs. Follow these steps to set the configuration: + +1. Go to [GraphOS Studio](https://studio.apollographql.com?referrer=docs-content). +2. Open the **Cloud Router** page from the left navigation. +3. Open the **Configuration** tab. +4. In **Router configuration YAML**, ensure your configuration has the following configuration block: + +```yaml +include_subgraph_errors: + all: true +``` + +5. Click the **Save** button in the top right corner of that section. + +Configuration changes trigger a new launch. Please wait a few minutes for your cloud router to update with this new configuration. You can track your graph variant's deployment status on its **Launches** page. + +Once you've found and resolved the issue, Apollo recommends turning off subgraph error inclusion. To do so, remove the `include_subgraph_errors` configuration. Then, save the router's configuration YAML. + +## Common issues and errors + +If you encounter an error not listed below and need help, don't hesitate to get in touch with your Apollo contact. We're here to help. + +### Overriding `host` headers + +Amazon VPC Lattice relies on the `host` header to secure and route requests. You can't change this header on Cloud Dedicated. Instead, consider using a header like `x-host`. You can rewrite an incoming header through your [router configuration](/graphos/routing/cloud/dedicated-quickstart#step-3-inspect-and-configure-your-cloud-router) YAML: + +```yaml title="router.yaml" +# ...other configuration... +headers: + all: # Header rules for all subgraphs + request: + - propagate: + named: 'host' + rename: 'x-host' +``` + +The previous example renames a `host` header to `x-host`. + +### Service in resource share doesn't appear in private subgraphs + +Cloud Dedicated doesn't automatically scan your resource shares for new Lattice services. [Adding a subgraph](/graphos/routing/cloud/lattice-configuration#setup-for-existing-graphs) or [creating a new graph](/graphos/routing/cloud/lattice-configuration#setup-for-new-graphs) automatically triggers a scan for new Lattice services. If you can't view the latest resource shares for your graph, please get in touch for additional support. + +### Providing `Authorization` headers + +Because AWS Sigv4 relies on the [HTTP `Authorization` request header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization) for [signing requests](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html), you may receive an error like this: `You must be authenticated to access this resource. Please provide a valid Bearer Token in the Authorization header.` + +If your subgraphs rely on the `Authorization` header for authentication, your router must [rename](/graphos/routing/header-propagation/#propagate) it. For example: + +```yaml title="router.yaml" +# ...other configuration... +headers: + all: # Header rules for all subgraphs + request: + - propagate: + named: 'Authorization' + rename: 'X-Authorization' +``` + +Then, update your subgraphs to check for `Authorization` or your new header name. + +### Error trying to connect: Connection reset by peer (os error 104) + +This error is likely to occur when your cloud router tries to send traffic to a port different from the listener on your AWS VPC Lattice service. Apollo GraphOS Cloud only supports communicating with private subgraphs over HTTPS on port 443. + +You can check that a Lattice service is configured to receive traffic on the right port on a service's **Routing** page: + +1. In the AWS Console for your region of choice, go to the VPC service page. +2. In the left navigation, scroll down and open **VPC Lattice > Services**. +3. Click the Lattice service used by the subgraph in question. +4. Click the **Routing** tab. + +AWS VPC Lattice routing + +5. Check that you have a listener with a `protocol:port` configuration of **HTTPS:443**. + +If not, you must create a new listener by clicking on the **Add listener** button at the top left of this section. +Refer to step 10 of [Create a Lattice service](/graphos/routing/cloud/lattice-configuration#step-2-create-a-lattice-service) for more details. + +### HTTP fetch failed from '\_subgraph\_': 403: Forbidden + +This error likely occurs for one of the following reasons: + +- One of your clients is sending a subscription request to a private subgraph over WebSockets. +- The VPC Lattice IAM policy doesn't allow traffic from Apollo GraphOS Cloud. + +#### Subscriptions over WebSockets + +Subscriptions over WebSockets aren't supported in AWS VPC Lattice, as the platform currently [lacks WebSocket support](https://docs.aws.amazon.com/vpc-lattice/latest/ug/listeners.html#listener-configuration). When sending a request to upgrade to a WebSockets connection, Lattice returns a blank response with a 403 response code. In this situation, Lattice also doesn't emit access log entries to Amazon CloudWatch Logs. [Contact your AWS account team](https://aws.amazon.com/contact-us/sales-support/) to notify them of your interest in this feature. + +#### VPC Lattice IAM policy + +You can check that a Lattice service is configured to allow traffic from Apollo GraphOS Cloud on the service's **Access** page: + +1. In the AWS Console for your region of choice, go to the VPC service page. +2. In the left navigation, scroll down and open **VPC Lattice > Services**. +3. Click the Lattice service used by the subgraph in question. +4. Click the **Access** tab. +5. Ensure that the Auth type is set to **IAM** and that the policy looks like this: + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": "*", + "Action": "vpc-lattice-svcs:Invoke", + "Resource": "*", + "Condition": { + "ForAnyValue:StringLike": { + "aws:PrincipalOrgPaths": "o-9vaxczew6u/*/ou-leyb-l9pccq2t/ou-leyb-fvqz35yo/*" + } + } + } + ] +} +``` diff --git a/docs/source/routing/cloud/migrate-to-dedicated.mdx b/docs/source/routing/cloud/migrate-to-dedicated.mdx new file mode 100644 index 0000000000..96a5bddb01 --- /dev/null +++ b/docs/source/routing/cloud/migrate-to-dedicated.mdx @@ -0,0 +1,54 @@ +--- +title: Migrate to Dedicated +subtitle: Learn what to consider when migrating to a Dedicated cloud router +description: Migrate your self-hosted GraphQL APIs to a federated cloud supergraph with a pre-provisioned router on dedicated infrastructure. +--- + + + +GraphOS supports [self-hosted and cloud graphs](../../graphs/#graph-types), each recommended for different use cases. You may want to migrate to a cloud graph in these scenarios: + +- You have multiple GraphQL APIs you want to compose into a supergraph. +- You have one or more self-hosted GraphQL APIs and want to use GraphOS features beyond graph composition, for example, [`@defer` support](/graphos/routing/operations/defer) or [metrics reporting](/graphos/platform/insights/). +- You have a self-hosted supergraph and want to offload the management of your router service to Apollo while retaining or gaining access to premium router features like [subscription support](/graphos/routing/operations/subscriptions/), [authentication](/router/configuration/authn-jwt), and [more](/router/enterprise-features). Your router service may be either the GraphOS Router or the `@apollo/gateway` package. + +GraphOS offers two tiers of cloud routing: Serverless and Dedicated. This guide focuses on considerations when migrating to [Dedicated](/graphos/routing/cloud/dedicated). Refer to [this router comparison](/graphos/routing#router-comparison) to learn about the differences. + + + +Dedicated cloud routers currently support all [premium router features](/router/enterprise-features) except for [safelisting with persisted queries](/graphos/routing/security/persisted-queries/), [automatic persisted queries](/apollo-server/performance/apq/), and [offline licenses](/router/enterprise-features/#offline-enterprise-license). Support for both persisted queries features is on the roadmap. + + + +## Migrating from `@apollo/gateway` + +Cloud routers use the same [Apollo Router Core binary](https://github.com/apollographql/router) that you can self-host. Therefore, migrating from [`@apollo/gateway`](/apollo-server/using-federation/api/apollo-gateway/) entails migrating to the Apollo Router Core. Refer to the [Gateway migration guide](/graphos/reference/migration/from-gateway) for tips. + +## Router customizations + +The GraphOS Router supports a [few avenues for customization](/router/customizations/overview): + +- Custom router binaries +- Rhai scripting +- External coprocessing + +As a managed service, cloud routers don't support running custom binaries. Cloud routers don't currently support Rhai scripts, though support is on the roadmap. +Therefore, you must migrate any customizations to [external coprocessors](/graphos/routing/customization/coprocessor/) or built-in router features to use cloud routing. + +Built-in router features that you may have previously supported with customizations include: + +- [Authentication](/router/configuration/authn-jwt) +- [Telemetry and monitoring](/router/configuration/telemetry/overview) +- [Traffic shaping](/router/configuration/traffic-shaping) + +See the [router configuration documentation](/graphos/routing) for a full list of features. + +## Migration + +Once your implementation is ready to run on the router, including customizations, you can follow the [Dedicated quickstart](/graphos/routing/cloud/dedicated-quickstart) to get started. + +## Pricing considerations + +Cloud Dedicated pricing depends on throughput instead of operation volume. Refer to the [Throughput guide](/graphos/routing/cloud/throughput-guide) to learn more. + +When you no longer host your router, router-to-subgraph communication may be inter-region, inter-Availablity Zone (AZ), or egress traffic. Be aware of how your new network topology may affect your cloud costs. diff --git a/docs/source/routing/cloud/secure-subgraphs.mdx b/docs/source/routing/cloud/secure-subgraphs.mdx new file mode 100644 index 0000000000..974974ecd2 --- /dev/null +++ b/docs/source/routing/cloud/secure-subgraphs.mdx @@ -0,0 +1,89 @@ +--- +title: Secure Subgraphs +subtitle: Restrict access to your cloud supergraph using secrets +description: Generate a shared secret and configure your graph router and subgraphs to secure your federated GraphQL API. +redirectFrom: + - /graphos/graphs/securing-a-subgraph +--- + +To keep your supergraph secure, it's important that your individual subgraphs are [queried only by your router](/federation/building-supergraphs/subgraphs-overview/#securing-your-subgraphs). That's because your subgraphs expose powerful fields that the router uses to execute operations across them. External clients should not have access to these fields. + +To restrict subgraph communication to only your router, Apollo recommends creating a separate shared secret for each of your subgraphs. Whenever your router queries a subgraph, it includes that subgraph's corresponding secret in an HTTP header. + +## Secure your graph using secrets + +This article describes steps for securing your subgraphs when using a [cloud supergraph](/graphos/routing/cloud). + + + +As with all changes, we recommend first performing these steps for a non-production variant of your supergraph. + + + +### Step 1. Generate a shared secret + +You can generate a random secret using a variety of tools. For example, most password managers provide this functionality. + +Here are some shell commands that generate a suitably random secret if you have the corresponding tool installed: + +- `openssl rand -base64 256` +- `python -c "import secrets; print(secrets.token_urlsafe(256))"` +- `node -e "console.log(require('crypto').randomBytes(256).toString('base64'));"` + +### Step 2. Add the secret to your router config + +Your cloud supergraph's router needs to know the shared secret so it can include it in all requests to the corresponding subgraph. You add the secret in the **Cloud Routing** section of your graph variant's Settings page. + + + +For details, see [Managing secrets](/graphos/routing/cloud/configuration#managing-secrets). + + + +After you define the secret, you can inject its value into your router's configuration as an environment variable, as shown below. We recommend setting the value in a header named `Router-Authorization` (and again, create a separate secret for each subgraph): + +```yaml +headers: + subgraphs: + products: + request: + - insert: + name: 'Router-Authorization' + value: '${env.PRODUCTS_SUBGRAPH_SECRET}' + users: + request: + - insert: + name: 'Router-Authorization' + value: '${env.USERS_SUBGRAPH_SECRET}' +``` + +### Step 3. Configure the subgraph to require the secret + +The exact steps you take to require the shared secret in your subgraph depend on: + +- The language and framework your subgraph uses +- The service you use to host your subgraph + +Most cloud providers include a mechanism for saving secrets that are then made available to your application as environment variables. Your subgraph should read the secret from an environment variable and reject any incoming requests that don't include that secret in the specified header. + + + +All subgraph templates [provided by the Rover CLI](/graphos/graphs/creating-a-subgraph#starting-from-a-template) include this functionality out of the box. To use it, set the value of the `ROUTER_SECRET` environment variable. + +If you have an existing subgraph that wasn't created from a template, you can check a similar template's source code for an example. + + + +### Step 4. Test the configuration + +After adding the shared secret to both your router and subgraph, do the following to confirm that communication has been secured as intended: + +1. Verify that your router can still communicate with the subgraph by executing a test query against the router from the Explorer. + - Make sure the query includes at least one field from the relevant subgraph! +2. Verify that other clients can't communicate with the subgraph by executing a test query against the subgraph directly. + - This query should fail with an authorization error. + +## Next steps + +You can use router configurations such as JWT authentication, authorization, and safelisting to further secure your graph. +Check out the router configuration [security section](../../routing/security) to learn more. diff --git a/docs/source/routing/cloud/serverless.mdx b/docs/source/routing/cloud/serverless.mdx new file mode 100644 index 0000000000..027d6916f9 --- /dev/null +++ b/docs/source/routing/cloud/serverless.mdx @@ -0,0 +1,50 @@ +--- +title: Cloud Serverless Overview +subtitle: Learn about Serverless cloud routing use cases and limitations +description: Learn about Apollo GraphOS Serverless cloud routers, including intended use cases, limitations, and router statuses. +--- + + + +GraphOS Serverless cloud routers run on shared infrastructure that Apollo manages. Serverless is for demos, proof-of-concepts, and small production apps that don't need more than ten requests per second (RPS). + +## Serverless compute limitations + +The following circumstances can exhaust Serverless capacity: + +- Complex schemas can exceed available machine memory for Serverless routers. For example, Serverless routers don't support schemas with over 1,000 input types. +- Too many requests at once can overload your Serverless cloud router. It will return 429 errors to your clients. + +Because of these limitations, certain workloads might require you to upgrade to Dedicated. + +## Automatic deletion of unused routers + +When a Serverless cloud router goes 30 days without a request, Apollo deletes the router. +To avoid deletion, run a GraphQL operation on the router before the 30-day limit. + +Learn more about Serverless router statuses leading up to deletion in the next section. + +## Serverless router status + +All cloud routers can have **Initializing**, **Running**, and **Error** [statuses](../#cloud-router-status). Serverless cloud routers have these additional statuses: + +| Status | Description | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Running, will sleep soon** | Your cloud router hasn't received requests for six days and is scheduled to go to sleep soon. | +| **Sleeping** | Your cloud router hasn't received requests for seven days and is now sleeping. [Learn more.](#sleeping) | +| **Waking** | Your cloud router was asleep and recently received requests. You may experience API downtime for approximately one minute and up to five minutes. | +| **Sleeping, will delete soon** | Your cloud router has been asleep for almost 30 days and will be deleted soon. | +| **Deleted** | Your cloud router has been deleted but the associated graph variant remains. You can recreate a cloud router at anytime. [Learn more.](#deleted) | + +### Sleeping + +Serverless cloud routers go to sleep if they haven't received requests for seven days. While sleeping, your cloud router can't serve requests. + +Sleeping cloud routers automatically wake up once they receive requests. While waking, your cloud router can't process incoming requests. It typically takes about one minute to wake up. + +### Deleted + +If a cloud router has been sleeping for 30 days, Apollo automatically deletes it. +Router deletion doesn't delete the associated graph variant from GraphOS Studio, but it does spin down the infrastructure powering your cloud router. + +You can access a deleted router's [config](/graphos/reference/router/configuration) and its variant's schema, but you can't recover any [secrets that were stored in GraphOS Studio](/graphos/routing/cloud/configuration#managing-secrets). The variant's metrics are only kept for a day after deletion per the [Serverless data retention policy](https://www.apollographql.com/pricing#data-retention). diff --git a/docs/source/routing/cloud/subscriptions.mdx b/docs/source/routing/cloud/subscriptions.mdx new file mode 100644 index 0000000000..e522843b62 --- /dev/null +++ b/docs/source/routing/cloud/subscriptions.mdx @@ -0,0 +1,219 @@ +--- +title: GraphQL Subscriptions in Cloud Supergraphs +subtitle: Real-time data delivery across your services +description: Cloud routers support GraphQL subscriptions by default, enabling clients to receive real-time updates via WebSocket or HTTP callbacks. +redirectFrom: + - /graphos/operations/subscriptions +--- + + + +Cloud supergraph support for GraphQL subscriptions is currently in [preview](/graphos/reference/feature-launch-stages#preview). + +You can also use subscriptions with an Enterprise self-hosted supergraph. See the [GraphOS Router documentation](/graphos/routing/operations/subscriptions/). + + + +Cloud supergraphs provide preview support for GraphQL subscription operations: + +```graphql +subscription OnStockPricesChanged { + stockPricesChanged { + symbol + price + } +} +``` + +With a cloud supergraph, you can add `Subscription` fields to the schema of any subgraph that supports the [`graphql-transport-ws` WebSocket protocol](https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md): + +```graphql title="stocks.graphql" +type Subscription { + stockPricesChanged: [Stock!]! +} +``` + +Clients can then execute subscriptions on your cloud router, which executes them on your subgraphs. + +## Prerequisites + +Before you add `Subscription` fields to your subgraphs, do all the following in the order shown to prevent errors: + +1. Make sure you've created a [cloud supergraph](/graphos/routing/cloud#cloud-supergraphs) and connected your GraphQL API to it. + +2. [Update your supergraph's build pipeline](/graphos/platform/graph-management/updates#2-update-your-build-pipeline) to use Apollo Federation 2.4 or later. + - Previous versions of Apollo Federation don't support subscription operations. +3. If your subgraph schemas specify an Apollo Federation version, modify them to use Apollo Federation 2.4 or later: + + ```graphql title="stocks.graphql" + extend schema + @link( + url: "https://specs.apollo.dev/federation/v2.4" #highlight-line + import: ["@key", "@shareable"] + ) + + type Subscription { + stockPricesChanged: [Stock!]! + } + ``` + + - You can skip modifying subgraph schemas that don't define any `Subscription` fields. + +4. In each subgraph with subscriptions, make sure the subgraph uses the [`graphql-transport-ws`](https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md) WebSocket protocol for subscriptions. + +5. In each subgraph with subscriptions, make sure the subgraph hosts its subscriptions WebSocket endpoint at the path `/ws`. + + - If your WebSocket endpoint is currently hosted at a different path, you can add `/ws` as an additional path instead of removing the original path. This is helpful if legacy clients will continue executing subscriptions on your subgraph directly using the original path. + +6. Deploy your updated subgraphs. + +After you complete these prerequisites, you begin [executing subscriptions](#example-execution) on your cloud router. + +## Default configuration + +Subscriptions are enabled automatically for GraphOS Cloud with the following default router configuration: + +```yaml +subscription: + enabled: true + mode: + passthrough: + all: + path: /ws +``` + +## Example execution + +Let's say our supergraph includes the following subgraphs and partial schemas: + + + +```graphql title="Products subgraph" +type Product @key(fields: "id") { + id: ID! + name: String! + price: Int! +} + +# highlight-start +type Subscription { + productPriceChanged: Product! +} +#highlight-end +``` + +```graphql title="Reviews subgraph" +type Product @key(fields: "id") { + id: ID! + reviews: [Review!]! +} + +type Review { + score: Int! +} +``` + + + +A client can execute the following subscription against our router: + + + +Remember, clients execute subscriptions against your router [over HTTP!](#how-it-works) + +Apollo Client for [Web](/react/data/subscriptions#http), [Kotlin](/kotlin/essentials/subscriptions#configuring-http-subscriptions), and [iOS](/ios/fetching/subscriptions#http) all support HTTP-based subscriptions. + + + +```graphql +subscription OnProductPriceChanged { + productPriceChanged { + # Defined in Products subgraph + name + price + reviews { + # Defined in Reviews subgraph! + score + } + } +} +``` + +When our router receives this operation, it executes a corresponding subscription operation against the Products subgraph (over a new WebSocket connection): + +```graphql +subscription { + productPriceChanged { + id # Added for entity fetching + name + price + # Reviews fields removed! + } +} +``` + + + +- This operation adds the `Product.id` field. The router needs `@key` fields of the `Product` entity to merge entity fields from across subgraphs. +- This operation removes all fields defined in the Reviews subgraph, because the Products subgraph can't resolve them. + + + +At any point after the subscription is initiated, the Products subgraph might send updated data to our router. Whenever this happens, the router does not immediately return this data to the client, because it's missing requested fields from the Reviews subgraph! + +Instead, our router executes a standard GraphQL query against the Reviews subgraph to fetch the missing entity fields: + +```graphql +query { + _entities(representations: [...]) { + ... on Product { + reviews { + score + } + } + } +} +``` + +After receiving this query result from the Reviews subgraph, our router combines it with the data from Products and returns the combination to the subscribing client. + +## Trying subscriptions with `curl` + +To quickly try out HTTP-based subscriptions without setting up an Apollo Client library, you can execute a `curl` command against your cloud router with the following format: + +```bash title="Example curl request" showLineNumbers=false + curl 'https://main--my-org-supergraph.apollographos.net/graphql' -v \ + -H 'accept: multipart/mixed; boundary="graphql"; subscriptionSpec=1.0, application/json' \ + -H 'content-type: application/json' \ + --data-raw '{"query":"subscription OnProductPriceChanged { productPriceChanged { name price reviews { score } } }","operationName":"OnProductPriceChanged"}' +``` + +This command creates an HTTP multipart request and keeps an open connection that receives new subscription data in multiple response parts: + +```text showLineNumbers=false disableCopy=true +--graphql +content-type: application/json + +{} +--graphql +content-type: application/json + +{"payload":{"data":{"productPriceChanged":{"name":"Croissant","price":400,"reviews":[{"score":5}]}}}} +--graphql +content-type: application/json + +{"payload":{"data":{"productPriceChanged":{"name":"Croissant","price":375,"reviews":[{"score":5}]}}}} +--graphql +content-type: application/json + +{"payload":{"data":{"productPriceChanged":{"name":"Croissant","price":425,"reviews":[{"score":5}]}}}} +--graphql-- +``` + + + +This example subscription only emits three events and then directly closes the connection. + +For more information on this multipart HTTP subscription protocol, see [this article](/graphos/routing/operations/subscriptions/multipart-protocol/). + + diff --git a/docs/source/routing/cloud/throughput-guide.mdx b/docs/source/routing/cloud/throughput-guide.mdx new file mode 100644 index 0000000000..aac6471315 --- /dev/null +++ b/docs/source/routing/cloud/throughput-guide.mdx @@ -0,0 +1,157 @@ +--- +title: Throughput Guide +subtitle: Understand GCU performance and scale your graph's capacity +description: Learn about Graph Compute Units (GCUs)โ€”a measure of throughputโ€”and how to calculate and manage them for your supergraph on GraphOS Dedicated +--- + + + +This guide covers: + +- An overview of _Graph Compute Units_ (GCUs) and their performance expectations +- How to calculate the number of GCUs your supergraph needs +- How to manage your supergraph's throughput capacity as needs change + +## Overview + +Cloud Dedicated pricing is based on the amount of Graph Compute Units (GCUs) needed to run your graph. A GCU is a unit of throughput capacity that takes into account: + +- Processing incoming GraphQL requests +- Making a query plan across subgraphs +- Securely routing traffic to your backend services + +GCUs run on [AWS in the region of your choice](/graphos/routing/cloud/dedicated#runs-on-aws). + +### Performance expectations + + + +While Cloud Dedicated is in [preview](#private-preview), these performance expectations may change. + + + +From a single GCU, you can expect the following baseline performance: + +- 25 requests per second (RPS) +- 150 subgraph RPS +- Up to 0.5 megabytes of response data per second + +GCU performance varies depending on [additional factors](#throughput-factors), such as payload size. For example, requests that return large payloads may decrease throughput below the baseline 25 RPS. Conversely, requests that return small amounts of data may achieve above the baseline 25 RPS. + +Apollo recommends [load testing](#load-testing) your GraphQL workload on Cloud Dedicated before going into production. + +### Throughput factors + +Beyond RPS, query complexity and response size influence GCU throughput. For example, the following scenarios would decrease relative GCU throughput: + +- Requests that query more than five subgraphs +- Requests that return hundreds or thousands of fields per operation + +Requests like this decrease throughput because they require additional compute resources to execute. +Factor in additional GCUs into your [GCU calculation](#gcu-calculation) if your supergraph receives complex queries or returns large responses. + + + +GCUs include burst capacity to handle the occasional complex query. A sustained period of complex queries can [exhaust this capacity](#rate-limiting). + + + +### Rate limiting + +GCUs aren't rate-limited. However, GCUs do offer a specific amount of throughput capacity. It's possible to temporarily burst GCU throughput for a few seconds. After this period, clients receive 429 errors. Apollo recommends adding retry logic to your clients to minimize dropped requests. + +## GCU calculation + +If you already use GraphOS, you can calculate your required GCUs using the operation metrics in GraphOS Studio. + +1. In [Studio](https://studio.apollographql.com?referrer=docs-content), go to the **Insights** page and select **Last month** as the timeframe. + +GraphOS Studio Insights page with timeframe selection + +2. Scroll down to the **Request Rate** chart. This chart shows the request rate in requests per minute (RPM). +3. To calculate your required requests per second (RPS), find the peak RPM and divide it by 60. +4. Since, as [a baseline](#performance-expectations), 1 GCU can serve 25 RPS, divide your peak RPS by 25 to calculate your required GCUs. + +GraphOS Studio Insights Request Rate chart with highlighted peak + +- In the example above, the peak is **19,000 RPM**. +- `19,000 / 60 = 317`, so the graph has a peak of **317 RPS**. +- `317 / 25 = 13`, so this workload requires at least **13 GCUs** to operate. + + + +Factor in additional GCUs if your supergraph serves [complex or large requests](#throughput-factors). + + + +### Load testing + +Before going into production on Cloud Dedicated, Apollo highly recommends running a load test to simulate production traffic. +For example, suppose you run a load test of 10% of a typical day's traffic, which runs well on a single GCU. That means you need at least 10 GCUs to operate your graph on a typical day. + +## Manage capacity + +Cloud Dedicated supports mission-critical production workloads, and you can scale performance to meet the needs of your GraphQL APIs. +Dedicated supports up to 10 GCUs per GraphOS variant. + +Dedicated starts with 1 GCU per variant. You can change a variant's GCUs via either: + +- [GraphOS Studio](#edit-gcus-in-studio) +- [The Platform API](#edit-gcus-via-api) + + + +GCU updates takes about one minute to provision. + + + +### Edit GCUs in Studio + +You can change a graph variant's GCUs from the **Cloud Router** page in Studio. +Click **Manage Capacity** to the right of **Router Capacity**. + +GraphOS Studio managed GCUs + +Then, select the number of GCUs required and click **Save changes**. + +### Edit GCUs via API + +You can change a graph variant's GCUs with the following mutation from the [GraphOS Platform API](/graphos/reference/platform-api/). + +```graphql +mutation Graph($graphId: ID!, $name: String!, $gcus: Int!) { + graph(id: $graphId) { + variant(name: $name) { + router { + setGcus(gcus: $gcus) { + ... on RouterGcusSuccess { + order { + id + } + } + } + } + } + } +} +``` + +This mutation requires setting the following variables: + +- `graphId`: a graph's ID is the first part of the graph's graph ref + - You can a graph's ID in GraphOS Studio under **Settings** > **This Graph** +- `name`: the variant name + - If you haven't set a variant name, the default is `current` +- `gcus`: the number of GCUs to provision for the variant diff --git a/docs/source/routing/configure-your-router.mdx b/docs/source/routing/configure-your-router.mdx new file mode 100644 index 0000000000..c5c835b946 --- /dev/null +++ b/docs/source/routing/configure-your-router.mdx @@ -0,0 +1,103 @@ +--- +title: Configuring a Router +subtitle: Learn to configure cloud-hosted and self-hosted routers +description: Learn how to configure the Apollo GraphOS Router with environment variables, command-line options and commands, and YAML configuration files. +redirectFrom: + - /router/configuration/overview/ +--- + +You can configure a router in multiple ways. Because cloud-hosted and self-hosted routers share the common foundation of Apollo Router Core, all routers support declarative configuration with a YAML file, usually named `router.yaml`. Differences between configuring cloud-hosted and self-hosted routers: + +- A cloud-hosted router is managed by Apollo and fully integrated with GraphOS, so its configuration is provided via the GraphOS Studio IDE. +- A self-hosted router is launched via command line, so its configuration includes command-line options and environment variables. + +| | Cloud-Hosted Router | Self-Hosted Router | +| --- | :---: | :---: | +| Studio IDE | ✅ | ❌ | +| YAML file | ✅ | ✅ | +| Command-line options | ❌ | ✅ | +| Environment variables | ❌ | ✅ | + + +## YAML file-based configuration + +Both cloud-hosted and self-hosted routers support YAML file-based configuration. You can edit a YAML file named `router.yaml` to declaratively configure your router. + +- For cloud-hosted routers, use GraphOS Studio to edit `router.yaml`. +- For self-hosted routers, edit a local `router.yaml` and run your router with the `--config` flag: + + ```bash + ./router --config router.yaml + ``` + + + +For self-hosted routers, run `router config schema` to print a JSON schema of all configuration options supported by your router. + + + +To learn more about router configuration options, go to [router configuration reference docs](/graphos/reference/router/configuration). + + +## Configuring a self-hosted router + +You provide the configuration for a self-hosted router when you run a router binary or deploy a router image. + +From a command line, the router accepts configuration flags and environment variables. + +The `--config` flag sets a path to a YAML configuration file. Use this flag to customize non-default settings for your router. + + ```bash + ./router --config router.yaml + ``` + +GraphOS Routers must set the following environment variables so that they can fetch their supergraph schemas from GraphOS: + - `APOLLO_KEY` sets the graph API key to use for authenticating with GraphOS + - `APOLLO_GRAPH_REF` sets the graph ref of the graph and variant in GraphOS + +You can run your router from the command line with these environment variables: + + ```bash + APOLLO_KEY="..." APOLLO_GRAPH_REF="..." ./router + ``` + +To learn more about configuration options available to self-hosted routers, go to [router configuration reference docs](/graphos/reference/router/configuration). + +## Configuring a cloud-hosted router + +You can manage a cloud router's configuration from [GraphOS Studio](https://studio.apollographql.com?referrer=docs-content): + +- Open Studio and go to the **Cloud Router** page +- In the **General** tab, you can view: + + - The URL of your router's GraphQL API endpoint. Every cloud router URL is on a subdomain of `apollographos.net` + - Your router's status and launch history + +In the **Configuration** tab, you can manage: + + - Secrets + - Your router's YAML-base configuration + + - A router on the **Serverless** plan has the following options available: + - HTTP headers + - CORS rules + - Subgraph error inclusion + - Introspection + +## Next steps + +Browse this section to learn how to configure various features of the router: + +- **Real-Time Operations** sets up a router to support various real-time operations + +- **Security** protects a router from malicious or malformed requests and operations + +- **Performance and Scaling** optimize a router's response latency and throughput + +- **Router Customization** can add custom functionality to a router with scripts and coprocessors that can hook into a router's request-handling pipeline. + + +> Haven't run a router with GraphOS yet? Try the [quickstart](/graphos/get-started/guides/quickstart) + +> Learn more about configuration options available to cloud-hosted routers, go to [router configuration reference docs](/graphos/reference/router/configuration). + diff --git a/docs/source/customizations/coprocessor.mdx b/docs/source/routing/customization/coprocessor.mdx similarity index 93% rename from docs/source/customizations/coprocessor.mdx rename to docs/source/routing/customization/coprocessor.mdx index f52f5bb4a8..fcea96f061 100644 --- a/docs/source/customizations/coprocessor.mdx +++ b/docs/source/routing/customization/coprocessor.mdx @@ -4,7 +4,7 @@ subtitle: Customize your router's behavior in any language description: Customize the Apollo GraphOS Router with external coprocessing. Write standalone code in any language, hook into request lifecycle, and modify request/response details. --- -import CoprocTypicalConfig from '../../shared/coproc-typical-config.mdx'; +import CoprocTypicalConfig from '../../../shared/coproc-typical-config.mdx'; @@ -22,7 +22,7 @@ When your coprocessor responds to these requests, its response body can modify [ ## How it works -Whenever your router receives a client request, at various **stages** in the [request-handling lifecycle](./rhai/#router-request-lifecycle) it can send HTTP POST requests to your coprocessor: +Whenever your router receives a client request, at various **stages** in the [request-handling lifecycle](/graphos/routing/customization/rhai/#router-request-lifecycle) it can send HTTP POST requests to your coprocessor: ```mermaid flowchart TB; @@ -50,7 +50,7 @@ flowchart TB; This diagram shows request execution proceeding "down" from a client, through the router, to individual subgraphs. Execution then proceeds back "up" to the client in the reverse order. -As shown in the diagram above, the `RouterService`, `SupergraphService`, `ExecutionService`, and `SubgraphService` steps of the [request-handling lifecycle](./rhai/#router-request-lifecycle) can send these POST requests (also called **coprocessor requests**). +As shown in the diagram above, the `RouterService`, `SupergraphService`, `ExecutionService`, and `SubgraphService` steps of the [request-handling lifecycle](/graphos/routing/customization/rhai/#router-request-lifecycle) can send these POST requests (also called **coprocessor requests**). Each supported service can send its coprocessor requests at two different **stages**: @@ -68,9 +68,9 @@ If your coprocessor hooks into your router's `SubgraphService`, the router sends ## Setup -First, make sure your router is [connected to a GraphOS Enterprise organization](../enterprise-features/#enabling-enterprise-features). +First, make sure your router is [connected to a GraphOS Enterprise organization](/router/enterprise-features/#enabling-enterprise-features). -You configure external coprocessing in your router's [YAML config file](../configuration/overview/#yaml-config-file), under the `coprocessor` key. +You configure external coprocessing in your router's [YAML config file](/router/configuration/overview/#yaml-config-file), under the `coprocessor` key. ### Typical configuration @@ -94,7 +94,7 @@ In this case, the `RouterService` only sends a coprocessor request whenever it r ### Conditions -You can define [conditions](../configuration/telemetry/instrumentation/conditions) for a stage of the request lifecycle that you want to run the coprocessor. You can set coprocessor conditions with [selectors](../configuration//telemetry//instrumentation/selectors) based on headers or context entries. +You can define [conditions](/router/configuration/telemetry/instrumentation/conditions) for a stage of the request lifecycle that you want to run the coprocessor. You can set coprocessor conditions with [selectors](/router/configuration/telemetry/instrumentation/selectors) based on headers or context entries. @@ -152,22 +152,6 @@ coprocessor: ``` -You can also change DNS resolution strategy applied to coprocessor's URL: -```yaml title="router.yaml" -coprocessor: - url: http://coprocessor.example.com:8081 - client: - dns_resolution_strategy: ipv4_then_ipv6 - -``` - -Possible strategies are: -* `ipv4_only` - Only query for `A` (IPv4) records. -* `ipv6_only` - Only query for `AAAA` (IPv6) records. -* `ipv4_and_ipv6` - Query for both `A` (IPv4) and `AAAA` (IPv6) records in parallel. -* `ipv6_then_ipv4` - Query for `AAAA` (IPv6) records first; if that fails, query for `A` (IPv4) records. -* `ipv4_then_ipv6`(default) - Query for `A` (IPv4) records first; if that fails, query for `AAAA` (IPv6) records. - ## Coprocessor request format The router communicates with your coprocessor via HTTP POST requests (called **coprocessor requests**). The body of each coprocessor request is a JSON object with properties that describe either the current client request or the current router response. @@ -800,7 +784,7 @@ A unique ID corresponding to the subgraph request associated with this coprocess -Indicates which stage of the router's [request-handling lifecycle](./rhai/#router-request-lifecycle) this coprocessor request corresponds to. +Indicates which stage of the router's [request-handling lifecycle](/graphos/routing/customization/rhai/#router-request-lifecycle) this coprocessor request corresponds to. This value is one of the following: @@ -872,7 +856,7 @@ This field's structure depends on whether the coprocessor request corresponds to - **If a standard response,** `body` usually contains `data` and/or `errors` properties for the GraphQL operation result. - **If a response "chunk",** `body` contains `data` for _some_ of the operation fields. -By default, the `RouterResponse` stage returns _redacted_ errors within the `errors` field. To process subgraph errors manually in your coprocessor, enable [subgraph error inclusion](../configuration/subgraph-error-inclusion). +By default, the `RouterResponse` stage returns _redacted_ errors within the `errors` field. To process subgraph errors manually in your coprocessor, enable [subgraph error inclusion](/router/configuration/subgraph-error-inclusion). @@ -1164,7 +1148,7 @@ If a request to a coprocessor results in a **failed response**, which is seperat ## Handling deferred query responses -GraphOS Router and Apollo Router Core support the incremental delivery of query response data via [the `@defer` directive](../executing-operations/defer-support/): +GraphOS Router and Apollo Router Core support the incremental delivery of query response data via [the `@defer` directive](/router/executing-operations/defer-support/): ```mermaid sequenceDiagram @@ -1245,7 +1229,7 @@ Subsequent response chunks omit the `headers` and `statusCode` fields: ## Adding authorization claims via coprocessor -To use the [authorization directives](../configuration/authorization#authorization-directives), a request needs to include **claims**โ€”the details of its authentication and scope. The most straightforward way to add claims is with [JWT authentication](../configuration/./authn-jwt). You can also add claims with a [`RouterService` or `SupergraphService` coprocessor](#how-it-works) since they hook into the request lifecycle before the router applies authorization logic. +To use the [authorization directives](/router/configuration/authorization#authorization-directives), a request needs to include **claims**โ€”the details of its authentication and scope. The most straightforward way to add claims is with [JWT authentication](/router/configuration/./authn-jwt). You can also add claims with a [`RouterService` or `SupergraphService` coprocessor](#how-it-works) since they hook into the request lifecycle before the router applies authorization logic. An example configuration of the router calling a coprocessor for authorization claims: @@ -1274,7 +1258,7 @@ This configuration prompts the router to send an HTTP POST request to your copro } ``` -When your coprocessor receives this request from the router, it should add claims to the request's [`context`](#context) and return them in the response to the router. Specifically, the coprocessor should add an entry with a claims object. The key must be `apollo_authentication::JWT::claims`, and the value should be the claims required by the authorization directives you intend to use. For example, if you want to use [`@requireScopes`](../configuration/authorization#requiresscopes), the response may look something like this: +When your coprocessor receives this request from the router, it should add claims to the request's [`context`](#context) and return them in the response to the router. Specifically, the coprocessor should add an entry with a claims object. The key must be `apollo_authentication::JWT::claims`, and the value should be the claims required by the authorization directives you intend to use. For example, if you want to use [`@requireScopes`](/router/configuration/authorization#requiresscopes), the response may look something like this: ```json { diff --git a/docs/source/customizations/custom-binary.mdx b/docs/source/routing/customization/custom-binary.mdx similarity index 96% rename from docs/source/customizations/custom-binary.mdx rename to docs/source/routing/customization/custom-binary.mdx index c2a6933146..87b87c2fae 100644 --- a/docs/source/customizations/custom-binary.mdx +++ b/docs/source/routing/customization/custom-binary.mdx @@ -4,8 +4,8 @@ subtitle: Compile a custom router binary from source description: Compile a custom Apollo Router Core binary from source. Learn to create native Rust plugins. --- -import ElasticNotice from '../../shared/elastic-notice.mdx'; -import NativePluginNotice from '../../shared/native-plugin-notice.mdx'; +import ElasticNotice from '../../../shared/elastic-notice.mdx'; +import NativePluginNotice from '../../../shared/native-plugin-notice.mdx'; Learn how to compile a custom binary from Apollo Router Core source, which is required to create custom native Rust plugins for the router. @@ -211,4 +211,4 @@ ENTRYPOINT ["/dist/router", "-s", "/dist/supergraph.graphql"] ## Related topics -* [Optimizing Custom Router Builds](/technotes/TN0030-optimizing-router-builds/) +* [Optimizing Custom Router Builds](/graphos/routing/self-hosted/containerization/optimize-build) diff --git a/docs/source/customizations/native.mdx b/docs/source/routing/customization/native-plugins.mdx similarity index 90% rename from docs/source/customizations/native.mdx rename to docs/source/routing/customization/native-plugins.mdx index 650dddcc58..aa27eb991c 100644 --- a/docs/source/customizations/native.mdx +++ b/docs/source/routing/customization/native-plugins.mdx @@ -4,10 +4,10 @@ subtitle: Extend the router with custom Rust code description: Extend the Apollo GraphOS Router or Apollo Router Core with custom Rust code. Plan, build, and register plugins. Define plugin configuration and implement lifecycle hooks. --- -import ElasticNotice from '../../shared/elastic-notice.mdx'; -import NativePluginNotice from '../../shared/native-plugin-notice.mdx'; +import ElasticNotice from '../../../shared/elastic-notice.mdx'; +import NativePluginNotice from '../../../shared/native-plugin-notice.mdx'; -Your federated graph might have specific requirements that aren't supported by the built-in [configuration options](../configuration/overview/) of the GraphOS Router or Apollo Router Core. For example, you might need to further customize the behavior of: +Your federated graph might have specific requirements that aren't supported by the built-in [configuration options](/router/configuration/overview/) of the GraphOS Router or Apollo Router Core. For example, you might need to further customize the behavior of: * Authentication/authorization * Logging @@ -23,7 +23,7 @@ In these cases, you can create custom plugins for the router. When designing a new plugin, you first want to determine which of the router's **services** the plugin should hook into to achieve its use case. -For descriptions of these services, see [Router request lifecycle](./rhai#router-request-lifecycle). +For descriptions of these services, see [Router request lifecycle](/graphos/routing/customization/rhai#router-request-lifecycle). ## Building a plugin @@ -57,7 +57,7 @@ struct Conf { } ``` -> **Note:** You need to `derive` `JsonSchema` so that your configuration can participate in [JSON schema generation](../configuration/overview/#configuration-awareness-in-your-text-editor). +> **Note:** You need to `derive` `JsonSchema` so that your configuration can participate in [JSON schema generation](/router/configuration/overview/#configuration-awareness-in-your-text-editor). Then define the plugin itself and specify the configuration as an associated type: @@ -237,7 +237,7 @@ Choose a group name that represents your organization and a name that represents ### 7. Configure your plugin -After you register your plugin, you need to add configuration for it to your [YAML configuration file](../configuration/overview/#yaml-config-file) in the `plugins:` section: +After you register your plugin, you need to add configuration for it to your [YAML configuration file](/router/configuration/overview/#yaml-config-file) in the `plugins:` section: ```yaml plugins: @@ -251,7 +251,7 @@ To create custom metrics, traces, and spans, you can use [`tracing` macros](http ### Add custom metrics -Make sure to [enable Prometheus metrics](../configuration/telemetry/exporters/metrics/prometheus) in your configuration if you want to have metrics generated by the router. +Make sure to [enable Prometheus metrics](/router/configuration/telemetry/exporters/metrics/prometheus) in your configuration if you want to have metrics generated by the router. @@ -295,7 +295,7 @@ tracing::info!( ### Add custom spans -Make sure to [enable OpenTelemetry tracing](../configuration/telemetry/exporters/tracing/overview) in your configuration if you want customize the traces generated and linked by the router. +Make sure to [enable OpenTelemetry tracing](/router/configuration/telemetry/exporters/tracing/overview) in your configuration if you want customize the traces generated and linked by the router. @@ -314,7 +314,7 @@ Like individual requests, plugins follow their own strict lifecycle that helps p ### Creation -When the router starts or reloads, it calls `new` to create instances of plugins that have configuration in the `plugins:` section of the [YAML configuration file](../configuration/overview/#yaml-config-file). If any of these calls fail, the router terminates with helpful error messages. +When the router starts or reloads, it calls `new` to create instances of plugins that have configuration in the `plugins:` section of the [YAML configuration file](/router/configuration/overview/#yaml-config-file). If any of these calls fail, the router terminates with helpful error messages. There is no sequencing for plugin registration, and registrations might even execute in parallel. A plugin should _never_ rely on the existence of _another_ plugin during initialization. @@ -322,9 +322,9 @@ There is no sequencing for plugin registration, and registrations might even exe Within a given service (router, subgraph, etc.), a _request_ is handled in the following order: -* [Rhai script](./rhai) -* [External coprocessor](./coprocessor) -* Rust plugins, in the same order they're declared in your [YAML configuration file](../configuration/overview/#yaml-config-file). +* [Rhai script](/graphos/routing/customization/rhai) +* [External coprocessor](/router/customizations/coprocessor) +* Rust plugins, in the same order they're declared in your [YAML configuration file](/router/configuration/overview/#yaml-config-file). The corresponding _response_ is handled in the opposite order. This ordering is relevant for communicating through [the `context` object](#5-define-necessary-context). diff --git a/docs/source/customizations/overview.mdx b/docs/source/routing/customization/overview.mdx similarity index 93% rename from docs/source/customizations/overview.mdx rename to docs/source/routing/customization/overview.mdx index 18e68103c2..c417b06d19 100644 --- a/docs/source/customizations/overview.mdx +++ b/docs/source/routing/customization/overview.mdx @@ -4,21 +4,21 @@ subtitle: Extend your router with custom functionality description: Extend the GraphOS Router or Apollo Router Core with custom functionality. Understand the request lifecycle and how customizations intervene at specific points. --- -You can create **customizations** for the GraphOS Router or Apollo Router Core to add functionality that isn't available via built-in [configuration options](../configuration/overview/). For example, you can make an external call to fetch authentication data for each incoming request. +You can create **customizations** for the GraphOS Router or Apollo Router Core to add functionality that isn't available via built-in [configuration options](/router/configuration/overview/). For example, you can make an external call to fetch authentication data for each incoming request. ## Customization types The GraphOS Router supports the following customization types: -- [**Rhai scripts**](./rhai/) +- [**Rhai scripts**](/graphos/routing/customization/rhai/) - The [Rhai scripting language](https://rhai.rs/book/) lets you add functionality directly to your stock router binary by hooking into different phases of the router's request lifecycle. -- [**External co-processing**](./coprocessor/) ([Enterprise feature](../enterprise-features/)) +- [**External co-processing**](/router/customizations/coprocessor/) ([Enterprise feature](/router/enterprise-features/)) - If your organization has a [GraphOS Enterprise plan](https://www.apollographql.com/pricing/), you can write custom request-handling code in any language. This code can run in the same container as your router or separately. - The router calls your custom code via HTTP, passing it the details of each incoming client request. -The Apollo Router Core supports customization only through [Rhai scripts](./rhai/). +The Apollo Router Core supports customization only through [Rhai scripts](/graphos/routing/customization/rhai/). -Because [Rhai scripts](./rhai/) are easier to deploy, we recommend using them if they support your use case. Use external co-processing if your customization needs to do any of the following (which Rhai scripts _don't_ support): +Because [Rhai scripts](/graphos/routing/customization/rhai/) are easier to deploy, we recommend using them if they support your use case. Use external co-processing if your customization needs to do any of the following (which Rhai scripts _don't_ support): - Read or write to disk - Make network requests @@ -295,4 +295,4 @@ This guidance applies if you are: ## Customization creation -To learn how to hook in to the various lifecycle stages, including examples customizations, refer to the [Rhai scripts](./rhai/) and [external coprocessing](./coprocessor/) docs. +To learn how to hook in to the various lifecycle stages, including examples customizations, refer to the [Rhai scripts](/graphos/routing/customization/rhai/) and [external coprocessing](/router/customizations/coprocessor/) docs. diff --git a/docs/source/customizations/rhai.mdx b/docs/source/routing/customization/rhai.mdx similarity index 97% rename from docs/source/customizations/rhai.mdx rename to docs/source/routing/customization/rhai.mdx index 6bad60dfe0..0716e19639 100644 --- a/docs/source/customizations/rhai.mdx +++ b/docs/source/routing/customization/rhai.mdx @@ -24,7 +24,7 @@ Common use cases for Rhai scripts in routers include: ## Setup -To enable Rhai scripts in your router, you add the following keys to the router's [YAML config file](../configuration/overview/#yaml-config-file): +To enable Rhai scripts in your router, you add the following keys to the router's [YAML config file](/router/configuration/overview/#yaml-config-file): ```yaml title="config.yaml" # This is a top-level key. It MUST define at least one of the two @@ -39,7 +39,7 @@ rhai: main: "test.rhai" ``` -1. Add the `rhai` top-level key to your router's [YAML config file](../configuration/overview/#yaml-config-file). +1. Add the `rhai` top-level key to your router's [YAML config file](/router/configuration/overview/#yaml-config-file). * This key **must** contain at least one of a `scripts` key or a `main` key (see the example above). 2. Place all of your Rhai script files in a specific directory. * By default, the router looks in the `./rhai` directory (relative to the directory the `router` command is executed from). @@ -194,7 +194,7 @@ Each service of the router has a corresponding function that a Rhai script can d Runs at the very beginning and very end of the HTTP request lifecycle. -For example, [JWT authentication](../configuration/authn-jwt) is performed within the `RouterService`. +For example, [JWT authentication](/router/configuration/authn-jwt) is performed within the `RouterService`. Define `router_service` if your customization needs to interact with HTTP `context` and `headers`. It doesn't support access to the `body` property (see [this GitHub issue](https://github.com/apollographql/router/issues/3642) for details). @@ -286,7 +286,7 @@ Each hook in your Rhai script's [main file](#main-file) is passed a `service` ob Additionally, callbacks for `subgraph_service` can access and modify the sub-operation request that the router will send to the corresponding subgraph via `request.subgraph`. - For reference, see the fields of [`request`](./rhai-api/#request-interface). + For reference, see the fields of [`request`](/graphos/reference/router/rhai/#request-interface). * `map_response` callbacks are called in each service as execution proceeds back "to the left" from subgraphs resolving their individual sub-operations: @@ -467,7 +467,7 @@ Currently, Rhai scripts _cannot_ do the following: * Execute network requests * Read or write to disk -If your router customization needs to do any of these, you can instead use [external co-processing](./coprocessor/) (this is an [Enterprise feature](../enterprise-features)). +If your router customization needs to do any of these, you can instead use [external co-processing](/router/customizations/coprocessor/) (this is an [Enterprise feature](/router/enterprise-features)). ### Global variables @@ -545,4 +545,4 @@ Syntax highlighting can make it easier to spot errors in a script. We recommend ### Logging -For tracking down runtime errors, insert [logging](./rhai-api#logging) statements to narrow down the issue. +For tracking down runtime errors, insert [logging](/graphos/reference/router/rhai#logging) statements to narrow down the issue. diff --git a/docs/source/configuration/telemetry/apollo-telemetry.mdx b/docs/source/routing/graphos-reporting.mdx similarity index 74% rename from docs/source/configuration/telemetry/apollo-telemetry.mdx rename to docs/source/routing/graphos-reporting.mdx index 4c2fb8d04f..56fb8e294a 100644 --- a/docs/source/configuration/telemetry/apollo-telemetry.mdx +++ b/docs/source/routing/graphos-reporting.mdx @@ -15,14 +15,55 @@ export APOLLO_KEY= export APOLLO_GRAPH_REF=@ ``` -For more information, see [Sending operation metrics to GraphOS](/graphos/metrics/sending-operation-metrics). + + +### Usage reporting via OpenTelemetry Protocol (OTLP) + + + +Prior to router v1.49.0, all GraphOS reporting was performed using a [private tracing format](/graphos/metrics/sending-operation-metrics#reporting-format) called Apollo Usage Reporting protocol. + +As the ecosystem around OpenTelemetry (OTel) has rapidly expanded, Apollo evaluated migrating its internal tracing system to use an OTel-based protocol. + +Starting in v1.49.0, the router can use OpenTelemetry Protocol (OTLP) to report operation usage metrics to GraphOS. The benefits of reporting via OTLP include: + +- A comprehensive way to visualize the router execution path in GraphOS Studio. +- Additional spans that were previously not included in Studio traces, such as query parsing, planning, execution, and more. +- Additional metadata such as subgraph fetch details, router idle / busy timing, and more. + +#### Configuring usage reporting via OTLP + +You can enable usage reporting via OTLP by an option that can also configure the ratio of traces sent via OTLP and Apollo Usage Reporting protocol: + +- In router v1.x, this is controlled using the `experimental_otlp_tracing_sampler` option and is disabled by default. + +The supported values of the OTLP sampler option are the following: + +- `always_off`: send all traces via Apollo Usage Reporting protocol. Default for v1.x. +- `always_on`: send all traces via OTLP. Default for v2.x and later. +- `0.0 - 1.0`: the ratio of traces to send via OTLP (for example, 0.6 = 60% OTLP, 40% Apollo Usage Reporting protocol). + +The OTLP sampler is applied _after_ the common tracing sampler. In the following example, the common sampler samples traces at 1% of all traffic. The OTLP sampler sets its ratio to 0.7. This results in 0.7% of all traffic having traces sent via OTLP, and the remaining 0.3% of all traffic having traces sent via Apollo Usage Reporting protocol: + +```yaml title="router.yaml" +telemetry: + apollo: + # Send 0.7 OTLP / 0.3 Apollo + experimental_otlp_tracing_sampler: 0.7 + + exporters: + tracing: + common: + # Sample traces at 1% of all traffic + sampler: 0.01 +``` ## Reporting field-level traces In their responses to your router, your subgraphs can include [field-level traces](/federation/metrics) that indicate how long the subgraph took to resolve each field in an operation. By analyzing this data in GraphOS Studio, you can identify and optimize your slower fields: Viewing a trace in GraphOS Studio -Because field-level instrumentation is dependent on general-purpose [OpenTelemetry tracing](./exporters/tracing/overview), the value of `telemetry.apollo.field_level_instrumentation_sampler` cannot exceed the value of `telemetry.exporters.tracing.common.sampler`. +Because field-level instrumentation is dependent on general-purpose [OpenTelemetry tracing](/router/configuration/telemetry/exporters/tracing/overview), the value of `telemetry.apollo.field_level_instrumentation_sampler` cannot exceed the value of `telemetry.exporters.tracing.common.sampler`. @@ -72,71 +113,6 @@ telemetry: field_level_instrumentation_sampler: always_off ``` - - -### Enhanced tracing in Studio via OpenTelemetry - - - - - -Beginning in v1.49.0, the router supports sending traces to Studio via the OpenTelemetry protocol (OTLP). -Support for OTLP traces has historically only been available for third-party APM tools. With this option, -Studio can now provide a much more granular and detailed view of router internals than the previous Apollo tracing protocol. -Support for OTel traces has historically only been available for 3rd party APM tools. With this option, -Studio can now provide a much more granular view of Router internals than the legacy Apollo tracing protocol. - -Benefits of OTLP traces include: - -- Comprehensive visualization of the router execution path in Studio -- New spans in Studio traces, including query parsing, planning, execution, and more -- New attributes, including HTTP request details, REST connector details, and more - - -#### Configuration - -You can configure OTel traces with the `telemetry.apollo.experimental_otlp_tracing_sampler` option. Use this option to send -a percentage of traces to Studio via OTLP instead of the native Apollo Usage Reporting protocol. Supported values: - -- `always_off` (default): send all traces via the legacy Apollo Usage Reporting protocol -- `always_on`: send all traces via OTLP -- `0.0 - 1.0` (used for testing): the ratio of traces to send via OTLP (0.4 = 40% OTLP / 60% legacy) - -This sampler is applied after the common tracing sampler. - -#### Example configuration - -An example configuration that samples 1% of traces and sends all traces via OTLP: - - -```yaml title="router.config.yaml" -telemetry: - apollo: - # Send all traces via OTLP - experimental_otlp_tracing_sampler: always_on - - exporters: - tracing: - common: - # Sample traces at 1% of all traffic - sampler: 0.01 -``` - -OTLP traces sent to Studio aren't necessarily identical to ones sent to third-party APM tools via OTLP: - -- Only specific OTLP attributes are included for parity with legacy traces today. This ensures that data privacy is maintained in an equivalent manner. Existing router configuration options for Apollo telemetry will continue to function with OTLP traces, including forwarding of GraphQL errors, headers, and variables. -- Some features of OTLP traces are available only in Studio and not in third-party APM tools, such as resolver-level timing information from [Federated Tracing](../../federation/metrics/#enabling-federated-tracing) - - - -You may experience an increase in tracing traffic sent to GraphOS Studio due to the additional detail captured by the new wire protocol. In exceptional situations, you may need to send fewer traces. - -To send fewer traces, configure `telemetry.exporters.tracing.common.sampler` or revert to the old protocol via `telemetry.apollo.otlp_tracing_sampler` to send fewer OTLP traces or to disable them. - -For performance regressions due to the new tracing protocol, you should report them to the [Apollo support team](https://www.apollographql.com/support). - - - ### Experimental local field metrics Apollo Router can send field-level metrics to GraphOS without using FTV1 tracing. This feature is experimental and is not yet displayable in GraphOS Studio. diff --git a/docs/source/executing-operations/requests.mdx b/docs/source/routing/guides/request-format.mdx similarity index 51% rename from docs/source/executing-operations/requests.mdx rename to docs/source/routing/guides/request-format.mdx index fff8c3eadd..baf03f633b 100644 --- a/docs/source/executing-operations/requests.mdx +++ b/docs/source/routing/guides/request-format.mdx @@ -1,16 +1,18 @@ --- title: Operation Request Format -subtitle: Send requests to the router over HTTP -description: Learn how to format and send GraphQL requests to Apollo GraphOS Router or Apollo Router Core over HTTP. Explore POST and GET examples and the automatic persisted queries protocol. +subtitle: Send requests to the Apollo Router over HTTP +description: Learn how to format and send GraphQL requests to Apollo Router over HTTP. Explore POST and GET examples and the automatic persisted queries protocol. +redirectFrom: + - /router/executing-operations/requests/ --- -By default, almost every GraphQL IDE and client library takes care of sending operations in a format that the GraphOS Router or Apollo Router Core supports. This article describes that format, which is also described on [graphql.org](https://graphql.org/learn/serving-over-http/) and in [this preliminary spec](https://github.com/graphql/graphql-over-http). +By default, almost every GraphQL IDE and client library takes care of sending operations in a format that the Apollo Router supports. This article describes that format, which is also described on [graphql.org](https://graphql.org/learn/serving-over-http/) and in [this preliminary spec](https://github.com/graphql/graphql-over-http). -The router accepts queries, mutations, and subscriptions sent as POST requests. It also accepts queries sent as GET requests. +The Apollo Router accepts queries, mutations, and subscriptions sent as POST requests. It also accepts queries sent as GET requests. ## POST requests -The router accepts POST requests with a JSON body. A valid request contains a `query` field, along with optional `variables` and an `operationName` (if `query` contains multiple possible operations). +The Apollo Router accepts POST requests with a JSON body. A valid request contains a `query` field, along with optional `variables` and an `operationName` (if `query` contains multiple possible operations). Let's say we want to execute the following query: @@ -43,13 +45,18 @@ curl --request POST \ https://rover.apollo.dev/quickstart/products/graphql ``` -The router's default landing page provides a `curl` command you can use to execute a test query on your own server: +The Apollo Router's default landing page provides a `curl` command you can use to execute a test query on your own server: - +```sh +curl --request POST \ + --header 'content-type: application/json' \ + --url 'http://127.0.0.1:4000/' \ + --data '{"query":"query { __typename }"}' +``` ## GET requests -The router also accepts GET requests for queries (but not mutations). With a GET request, query details (`query`, `operationName`, `variables`) are provided as URL query parameters. The `variables` option is a URL-escaped JSON object. +The Apollo Router also accepts GET requests for queries (but not mutations). With a GET request, query details (`query`, `operationName`, `variables`) are provided as URL query parameters. The `variables` option is a URL-escaped JSON object. Here's the same query from [POST requests](#post-requests) formatted for a `curl` GET request: @@ -60,8 +67,7 @@ curl --request GET \ ## Persisted queries protocol -The Automatic Persisted Queries (APQ) feature available for Apollo Router Core and the Persisted Query List (PQL) feature available for GraphOS Router use a separate protocol to send the operation document information in the `extensions`. This protocol can also use HTTP POST or GET. See the Apollo Client docs on the [APQ protocol](/react/api/link/persisted-queries/#protocol) for details. - +The Automatic Persisted Queries (APQ) and Persisted Query List (PQL) features of the Apollo Router use a separate protocol to send the operation document information in the `extensions`. This protocol can also use HTTP POST or GET. See the Apollo Client docs on the [APQ protocol](/react/api/link/persisted-queries/#protocol) for details. ## Related topics diff --git a/docs/source/configuration/header-propagation.mdx b/docs/source/routing/header-propagation.mdx similarity index 97% rename from docs/source/configuration/header-propagation.mdx rename to docs/source/routing/header-propagation.mdx index 686f269552..5d2fae3323 100644 --- a/docs/source/configuration/header-propagation.mdx +++ b/docs/source/routing/header-propagation.mdx @@ -6,7 +6,7 @@ description: Configure which HTTP headers the Apollo GraphOS Router or Apollo Ro You can configure which HTTP headers the GraphOS Router or Apollo Route Core includes in its requests to each of your subgraphs. You can define per-subgraph header rules, along with rules that apply to _all_ subgraphs. -You define header rules in your [YAML configuration file](./overview/#yaml-config-file), like so: +You define header rules in your [YAML configuration file](/router/configuration/overview/#yaml-config-file), like so: ```yaml title="router.yaml" # ...other configuration... @@ -214,7 +214,7 @@ headers: ## Response header propagation -It is not currently possible to propagate response headers from subgraphs to clients using YAML configuration alone. However, you _can_ achieve this using [Rhai scripting](../customizations/rhai). +It is not currently possible to propagate response headers from subgraphs to clients using YAML configuration alone. However, you _can_ achieve this using [Rhai scripting](/graphos/routing/customization/rhai). This approach relies on the fact that each request has a `context` object that can store data for the duration of that request: @@ -264,7 +264,7 @@ If you require a configuration-based solution for response header propagation, [ ## Propagation between subgraphs -It is not currently possible to propagate headers between subgraphs using YAML config alone. However, you _can_ achieve this using [Rhai scripting](../customizations/rhai). +It is not currently possible to propagate headers between subgraphs using YAML config alone. However, you _can_ achieve this using [Rhai scripting](/graphos/routing/customization/rhai). This approach relies on the fact that each request has a `context` object that can store data for the duration of that request: diff --git a/docs/source/managed-federation/client-awareness.mdx b/docs/source/routing/observability/client-awareness.mdx similarity index 96% rename from docs/source/managed-federation/client-awareness.mdx rename to docs/source/routing/observability/client-awareness.mdx index d27cb1aca5..f7660f85a8 100644 --- a/docs/source/managed-federation/client-awareness.mdx +++ b/docs/source/routing/observability/client-awareness.mdx @@ -10,7 +10,7 @@ The GraphOS Router and Apollo Router Core support [client awareness](/graphos/me ## Overriding client awareness headers -Different header names can be used by updating the configuration file. If those headers will be sent by a browser, they must be allowed in the [CORS (Cross Origin Resource Sharing) configuration](../configuration/cors), as follows: +Different header names can be used by updating the configuration file. If those headers will be sent by a browser, they must be allowed in the [CORS (Cross Origin Resource Sharing) configuration](/router/configuration/cors), as follows: ```yaml title="router.yaml" telemetry: diff --git a/docs/source/routing/observability/client-id-enforcement.mdx b/docs/source/routing/observability/client-id-enforcement.mdx new file mode 100644 index 0000000000..da882d2ba7 --- /dev/null +++ b/docs/source/routing/observability/client-id-enforcement.mdx @@ -0,0 +1,143 @@ +--- +title: Client ID Enforcement +subtitle: Require client details and operation names to help monitor schema usage +description: Improve GraphQL operation monitoring by tagging operations with with client details. See code examples for Apollo GraphOS Router and Apollo Server. +published: 2022-05-31 +id: TN0001 +tags: [server, observability, router] +redirectFrom: + - /technotes/TN0001-client-id-enforcement/ +--- + +As part of GraphOS Studio metrics reporting, servers can [tag reported operations with the requesting client's name and version](/graphos/metrics/client-awareness). This helps graph maintainers understand which clients are using which fields in the schema. + +Clients can (and should) also [name their GraphQL operations](/react/data/operation-best-practices/#name-all-operations), which provides more context around how and where data is being used. + +Together, these pieces of information help teams monitor their graph and make changes to it safely. We strongly encourage that your GraphQL gateway require client details and operation names from all requesting clients. + +## Enforcing in GraphOS Router + +The GraphOS Router supports client awareness by default if the client sets the `apollographql-client-name` and `apollographql-client-id` in their requests. These values can be overridden using the [router configuration file](/router/managed-federation/client-awareness/) directly. + +Client headers can also be enforced using a [Rhai script](/graphos/routing/customization/rhai) on every incoming request. + +```rhai title="client-id.rhai" +fn supergraph_service(service) { + const request_callback = Fn("process_request"); + service.map_request(request_callback); + } + +fn process_request(request) { + log_info("processing request"); + let valid_clients = ["1", "2"]; + let valid_client_names = ["apollo-client"]; + + if ("apollographql-client-version" in request.headers && "apollographql-client-name" in request.headers) { + let client_header = request.headers["apollographql-client-version"]; + let name_header = request.headers["apollographql-client-name"]; + + if !valid_clients.contains(client_header) { + log_error("Invalid client ID provided"); + throw #{ + status: 401, + message: "Invalid client ID provided" + }; + } + if !valid_client_names.contains(name_header) { + log_error("Invalid client name provided"); + throw #{ + status: 401, + message: "Invalid client name provided" + }; + } + } + else { + log_error("No client headers set"); + throw #{ + status: 401, + message: "No client headers set" + }; + } +} +``` + + + +If you're an enterprise customer looking for more material on this topic, try the [Enterprise best practices: Router extensibility](https://www.apollographql.com/tutorials/router-extensibility) course on Odyssey. + +Not an enterprise customer? [Learn about GraphOS for Enterprise.](https://www.apollographql.com/pricing) + + + +## Enforcing in Apollo Server + +If you're using Apollo Server for your gateway, you can require client metadata in every incoming request with a [custom plugin](/apollo-server/integrations/plugins/): + + + +The header names used below are the default headers sent by Apollo Client, but you can change them to whatever names your client uses. Additionally, these changes must be reflected in the [usage reporting plugin](/apollo-server/api/plugin/usage-reporting/#generateclientinfo) to report client headers to GraphOS. For an example, see [using custom client id headers](/apollo-server/monitoring/metrics#using-custom-headers). + + + + + +```ts title="index.ts" +function clientEnforcementPlugin(): ApolloServerPlugin { + return { + async requestDidStart() { + return { + async didResolveOperation(requestContext) { + const clientName = requestContext.request.http.headers.get("apollographql-client-name"); + const clientVersion = requestContext.request.http.headers.get("apollographql-client-version"); + + if (!clientName) { + const logString = `Execution Denied: Operation has no identified client`; + requestContext.logger.debug(logString); + throw new GraphQLError(logString); + } + + if (!clientVersion) { + const logString = `Execution Denied: Client ${clientName} has no identified version`; + requestContext.logger.debug(logString); + throw new GraphQLError(logString); + } + + if (!requestContext.operationName) { + const logString = `Unnamed Operation: ${requestContext.queryHash}. All operations must be named`; + requestContext.logger.debug(logString); + + throw new GraphQLError(logString); + } + }, + }; + }, + }; +} +const server = new ApolloServer({ + typeDefs, + resolvers, + plugins: [clientEnforcementPlugin()], +}); +``` + + + +## Adding enforcement for existing clients + +If clients are already consuming your graph and are not providing client metadata, adding universal enforcement will break those clients. To resolve this you should take the following steps: + +### Use other headers + +If you have other existing headers in your HTTP requests that can be parsed to extract some client info, you can extract the info from there. + +#### GraphOS Router + +Client awareness headers should be overridden using the [router configuration file](/router/managed-federation/client-awareness/#overriding-client-awareness-headers) to use the appropriate header names. + +#### Apollo Server + +If you do change the identifying headers, also update the [Usage Reporting Plugin](/apollo-server/api/plugin/usage-reporting) to use the new headers so that the proper client info is also sent to Studio. + +### Ask clients to update their requests + +The long-term fix will require that clients start sending the required headers needed to extract client info. While clients are working on updating their requests you can add the plugin code to your gateway, but instead of throwing an error you can log a warning so that the gateway team can track when all requests have been updated. diff --git a/docs/source/routing/observability/debugging-subgraph-requests.mdx b/docs/source/routing/observability/debugging-subgraph-requests.mdx new file mode 100644 index 0000000000..4e11c45962 --- /dev/null +++ b/docs/source/routing/observability/debugging-subgraph-requests.mdx @@ -0,0 +1,88 @@ +--- +title: Debugging Subgraph Requests from the GraphOS Router or @apollo/gateway +subtitle: Log query plans and subgraph calls to help debug problematic queries +description: Log query plans and subgraph calls with the Apollo GraphOS Router and @apollo/gateway to help debug problematic queries. +published: 2023-04-13 +id: TN0039 +tags: [federation, gateway, router, subgraphs] +redirectFrom: + - /technotes/TN0039-debugging-subgraph-requests/ +--- + +As your graph grows, you may need to debug a problematic query for one reason or another. The GraphOS Router and `@apollo/gateway` both serve as an entry point into your federated graph and offer ways to debug requests. + +Each client request goes through a process called [query planning](/graphos/explorer/additional-features/#query-plans-for-supergraphs) that generates the subgraph requests to execute. You can log out the query plan in both the router and gateway. + +## Output query plans with headers + +With router v0.16.0+ and `@apollo/gateway` v2.5.4+, you can pass the following headers to return the query plans in the GraphQL response extensions: + +- Including the `Apollo-Query-Plan-Experimental` header returns the query plan in the response extensions +- Additionally, including the `Apollo-Query-Plan-Experimental-Format` header with one of the supported options changes the output format: + - A value of `prettified` returns a human-readable string of the query plan + - A value of `internal` returns a JSON representation of the query plan + +## Log router subgraph calls + +If, instead, you want to debug your subgraph HTTP requests in a router instance, you can use [Rhai scripts](/graphos/routing/customization/rhai) to log the necessary information out. An example Rhai script is shown below. + + + +While it's possible to log out the variables, Apollo strongly recommends not +doing so to avoid leaking sensitive information into your logs. + + + +```rhai +fn subgraph_service(service, subgraph) { + service.map_request(|request| { + log_info(`Subgraph: ${subgraph} Query: ${request.subgraph.body.query}`); + }); +} +``` + +The above uses an inline closure within the `map_request` function of the `subgraph_service` hook to log the subgraph-related information. + +To enable query plans, you must run the router with the `--dev` flag and leverage [Apollo Sandbox](https://studio.apollographql.com/sandbox) to [display your query plans](/graphos/explorer/additional-features/#query-plans-for-supergraphs). + +As an alternative to using `--dev`, you can also enable query plans via the below configuration option, however, Apollo strongly discourages this as the feature may be removed or renamed in the future. + +```yaml +plugins: + experimental.expose_query_plan: true +``` + +## Log `@apollo/gateway` subgraph calls + +To debug queries to your subgraphs within an `@apollo/gateway` instance, you can use a [`buildService` function](/apollo-server/using-federation/api/apollo-gateway/#configuring-the-subgraph-fetcher) to log the operation name and body. + + + +While it's possible to log out the variables, Apollo strongly recommends not +doing so to avoid leaking sensitive information into your logs. + + + +```ts +class DebugDataSource extends RemoteGraphQLDataSource { + willSendRequest({ + request + }: GraphQLDataSourceProcessOptions< + Record + >): void | Promise { + console.log(`Operation name: ${request.operationName}`); + console.log(`Query body: ${request.query}`); + } +} +const gateway = new ApolloGateway({ + debug: true, + supergraphSdl, + buildService({url}) { + return new DebugDataSource({url}); + } +}); +``` + +The above snippet creates a new class called `DebugDataSource` to log out the operation name and body using the `willSendRequest` hook, which is called before execution. + +Lastly, it also enables the `debug` setting on the gateway configuration to print out query plans in the logs for further debugging if needed. diff --git a/docs/source/routing/observability/index.mdx b/docs/source/routing/observability/index.mdx new file mode 100644 index 0000000000..48d531e69f --- /dev/null +++ b/docs/source/routing/observability/index.mdx @@ -0,0 +1,67 @@ +--- +title: Observability with GraphOS +subtitle: Capture and export signals about supergraph health with GraphOS and router telemetry +description: Learn how to collect supergraph metrics in order to monitor and optimize your GraphQL usage and performance. Collect raw metrics, insights, and alerts with Apollo GraphOS, GraphOS Studio, and GraphOS Router and Apollo Router Core. +redirectFrom: + - /federation/performance/monitoring/ +--- + +Monitoring a supergraph requires gathering metrics about each client, server, subgraph, and router involved in sending or handling requests. Ideally, the entire request pipelineโ€”from client to router to subgraph and backโ€”is instrumented with metrics that can be collected and exported for analysis. + +Apollo GraphOS provides the observability signals and tools your team needs to maintain the health and performance of your deployed supergraphs. Via declarative configuration, GraphOS enables routers to collect GraphQL operation and field metrics and report them back. GraphOS also specifies how to capture metrics on the clients and subgraphs handling operations. + +## Understanding runtime health with router telemetry + +Both the GraphOS Router and Apollo Router Core run a request-handling pipeline with multiple stages that starts with receiving requests and ends with sending back responses. The continuous operation and throughput of this request pipeline, or "request lifecycle," reflects the health of a running supergraph. Observability of the router request lifecycle is therefore key to understanding the health of a supergraph. + + + +To enable observability, the router supports telemetry that can be added and customized in every stage of the router request lifecycle. You can add logs, metrics, and traces, and you can export them to your application performance monitoring (APM) solution. + +To learn more, go to [Router Telemetry](/graphos/routing/observability/telemetry), then browse the pages in [Router Telemetry](/graphos/reference/router/telemetry/log-exporters/overview) reference docs. + +## Automating supergraph metrics collection with GraphOS + +Everything connected to GraphOSโ€”including clients, routers, and subgraphsโ€”can report metrics about GraphQL operations they send and service. GraphOS thus is the hub for collecting operation metrics, and its Studio IDE offers tools to visualize and analyze those operations and their field usage. + +The metrics that GraphOS collects can be forwarded to your APM solution. Apollo offers a [Datadog integration](/graphos/platform/insights/datadog-forwarding) to forward your graph's performance metrics to your Datadog account. + + +## Analyzing metrics and gathering insights with GraphOS + +Once the various metrics are collected by GraphOS, you can use the GraphOS Studio UI to visualize and analyze them to understand your supergraph's usage and performance. + +- Examine them in the Studio IDE from any variant's **Insights** page and use them to improve your graph's performance. + +- Create GraphOS notifications to notify your team about changes to your graph and its performance. + + + +The following require an [Enterprise plan](https://www.apollographql.com/pricing/): + +
      +
      + +- Connecting a self-hosted router to GraphOS +- Forwarding metrics to Datadog + +
      + +Reporting metrics from [Apollo Server](/apollo-server) or a [monograph](/graphos/get-started/concepts/graphs/#monographs) requires an [Enterprise or legacy Team plan](https://www.apollographql.com/pricing). + +If your organization doesn't currently have an Enterprise plan, you can test out this functionality by signing up for a free [GraphOS trial](https://studio.apollographql.com/signup?referrer=docs-content). + +
      + + +## Next steps + +- Learn about metrics collection with [GraphOS Metrics Collection](/graphos/platform/insights/sending-operation-metrics). + +- Learn about subgraph observability with [Subgraph Observability](/graphos/routing/observability/subgraph-error-inclusion). + +- Learn about client observability with [Client Observability](/graphos/routing/observability/client-id-enforcement/). + +- Learn how to use insights to improve your graph's performance with [GraphOS Metrics and Insights](/graphos/platform/insights/). + +- Learn how to use notifications with [GraphOS notifications](/graphos/platform/insights/notifications). diff --git a/docs/source/routing/observability/otel-traces-to-prometheus.mdx b/docs/source/routing/observability/otel-traces-to-prometheus.mdx new file mode 100644 index 0000000000..08841ed1b0 --- /dev/null +++ b/docs/source/routing/observability/otel-traces-to-prometheus.mdx @@ -0,0 +1,106 @@ +--- +title: Connecting OpenTelemetry Traces to Prometheus +id: TN0003 +subtitle: Convert operation traces into aggregated metrics for a broader view of your graph's performance +description: Convert operation traces into aggregated metrics using OpenTelemetry Collector and Prometheus for a broader view of your graph's performance. +published: 2022-06-03 +tags: [server, observability] +redirectFrom: + - /technotes/TN0003-opentelemetry-traces-to-prometheus/ +--- + + + +Self-hosting the GraphOS Router is limited to [GraphOS Enterprise plans](https://www.apollographql.com/pricing). Other plan types use [managed cloud routing with GraphOS](/graphos/cloud-routing). Check out the [pricing page](https://www.apollographql.com/pricing#graphos-router) to learn more. + + + + + +If you're an enterprise customer looking for more material on this topic, try the [Enterprise best practices: Supergraph observability](https://www.apollographql.com/tutorials/supergraph-observability) course on Odyssey. + +Not an enterprise customer? [Learn about GraphOS for Enterprise.](https://www.apollographql.com/pricing) + + + +Operation traces provide insight into performance issues that are occurring at various execution points in your graph. However, individual traces don't provide a view of your graph's broader performance. + +Helpfully, you can convert your operation traces into aggregated metrics without requiring manual instrumentation. To accomplish this, we'll use `spanmetricsprocessor` in an OpenTelemetry Collector instance to automatically generate metrics from our existing trace spans. + +## OpenTelemetry Collector configuration + +OpenTelemetry provides two different repositories for their OpenTelemetry Collector: + +- The [core library](https://github.com/open-telemetry/opentelemetry-collector) +- The [contributor library](https://github.com/open-telemetry/opentelemetry-collector-contrib) + +These repositories are similar in scope, but the contributor library includes extended features that aren't suitable for the core library. To derive performance metrics from our existing spans, we'll use the contributor library to take advantage of the `spanmetricsprocessor` via the associated Docker image. + + + +We also recommend checking out the [Collector Builder](https://github.com/open-telemetry/opentelemetry-collector/tree/main/cmd/builder) to build binaries that are tailored to your environment instead of relying on prebuilt images. + + + +When your OpenTelemetry Collector is ready to run, you can start configuring it with this barebones example: + +```yaml +receivers: + otlp: + protocols: + grpc: + http: + cors: + allowed_origins: + - http://* + - https://* + otlp/spanmetrics: + protocols: + grpc: + endpoint: 0.0.0.0:12346 + +exporters: + prometheus: + endpoint: '0.0.0.0:9464' + +processors: + batch: + spanmetrics: + metrics_exporter: prometheus + +service: + pipelines: + traces: + receivers: [otlp] + processors: [spanmetrics, batch] + metrics: + receivers: [otlp/spanmetrics] + exporters: [prometheus] + processors: [batch] +``` + +## Apollo Server setup + +Add the OTLP Exporter (`@opentelemetry/exporter-trace-otlp-http` Node package) following the same instructions [as shown in the documentation for Apollo Server and OpenTelemetry.](/federation/opentelemetry/) + +## GraphOS Router setup + +To send traces from the GraphOS Router to OpenTelemetry Collector, see [this article](/router/configuration/telemetry/exporters/tracing/otlp). + +## Prometheus setup + +Lastly, we need to add the OpenTelemetry Collector as a target within Prometheus. It'll use the standard port for Prometheus metrics (`9464`). + +That's it- you should have access to span metrics using the same operation name! + +## Example queries + +Here are a few sample queries to help explore the data structure being reported: + +- P95 by service:ย `histogram_quantile(.95, sum(rate(latency_bucket[5m])) by (le, service_name))` +- Average latency by service and operation (for example `router` / `graphql.validate`):ย `sum by (operation, service_name)(rate(latency_sum{}[1m])) / sum by (operation, service_name)(rate(latency_count{}[1m]))` +- RPM by service:ย `sum(rate(calls_total{operation="HTTP POST"}[1m])) by (service_name)` + +## Full demo + +To see this in action, check out the [Supergraph Demo](https://github.com/apollographql/supergraph-demo-fed2#tracing-with-open-telemetry) repository using the OpenTelemetry-Collector-specific Docker Compose image. diff --git a/docs/source/configuration/subgraph-error-inclusion.mdx b/docs/source/routing/observability/subgraph-error-inclusion.mdx similarity index 84% rename from docs/source/configuration/subgraph-error-inclusion.mdx rename to docs/source/routing/observability/subgraph-error-inclusion.mdx index f56bcf92ba..d991a3e710 100644 --- a/docs/source/configuration/subgraph-error-inclusion.mdx +++ b/docs/source/routing/observability/subgraph-error-inclusion.mdx @@ -14,7 +14,7 @@ This redaction prevents potential leaks of sensitive information to the client. ## Configuration -To configure subgraph error inclusion, add the `include_subgraph_errors` plugin to your [YAML config file](./overview/#yaml-config-file), like so: +To configure subgraph error inclusion, add the `include_subgraph_errors` plugin to your [YAML config file](/router/configuration/overview/#yaml-config-file), like so: ```yaml title="router.yaml" include_subgraph_errors: @@ -26,8 +26,8 @@ include_subgraph_errors: Any configuration under the `subgraphs` key takes precedence over configuration under the `all` key. In the example above, subgraph errors are included from all subgraphs _except_ the `products` subgraph. ## Sending errors to GraphOS -To report the subgraph errors to GraphOS that is a separate configuration that is not affected by client subgraph error inclusion, see the [GraphOS reporting docs](./telemetry/apollo-telemetry). +To report the subgraph errors to GraphOS that is a separate configuration that is not affected by client subgraph error inclusion, see the [GraphOS reporting docs](/router/configuration/telemetry/apollo-telemetry). ## Logging GraphQL request errors -To log the GraphQL error responses (i.e. messages returned in the GraphQL `errors` array) from the router, see the [logging configuration documentation](./telemetry/exporters/logging/overview). +To log the GraphQL error responses (i.e. messages returned in the GraphQL `errors` array) from the router, see the [logging configuration documentation](/router/configuration/telemetry/exporters/logging/overview). diff --git a/docs/source/configuration/telemetry/overview.mdx b/docs/source/routing/observability/telemetry.mdx similarity index 76% rename from docs/source/configuration/telemetry/overview.mdx rename to docs/source/routing/observability/telemetry.mdx index 076630210a..fc593d8dd0 100644 --- a/docs/source/configuration/telemetry/overview.mdx +++ b/docs/source/routing/observability/telemetry.mdx @@ -6,12 +6,6 @@ description: Observe and monitor the health and performance of GraphQL operation import TelemetryPerformanceNote from '../../../shared/telemetry-performance.mdx'; - - In this overview, learn about: - How GraphOS Router and Apollo Router Core telemetry enable supergraph observability and debuggability - What data is captured in the router's logs, metrics, and traces @@ -32,7 +26,7 @@ flowchart LR ## Observability through telemetry -The health of your supergraph is only as good as the health of your router. Because the router is the single entry point to the supergraph, all client requests pass through the [router's request lifecycle](../../customizations/overview#the-request-lifecycle). Any issues with the router are likely to affect the handling of all requests to your supergraph. +The health of your supergraph is only as good as the health of your router. Because the router is the single entry point to the supergraph, all client requests pass through the [router's request lifecycle](/router/customizations/overview#the-request-lifecycle). Any issues with the router are likely to affect the handling of all requests to your supergraph. Diagnosing your router's health and performance requires it to show observable data about its inner workings. The more observable data you can monitor and analyze, the faster you can identify unhealthy behaviors, deduce root causes, and implement fixes. @@ -98,13 +92,13 @@ Logs record **events** in the router. Examples of logged events include: * Warnings about misconfiguration * Errors that occurred during a request -Logs can be consumed by [logging exporters](./exporters/logging/overview) and as part of [spans](#traces-and-spans) via [tracing exporters](./exporters/tracing/overview). +Logs can be consumed by [logging exporters](/router/configuration/telemetry/exporters/logging/overview) and as part of [spans](#traces-and-spans) via [tracing exporters](/router/configuration/telemetry/exporters/tracing/overview). ### Metrics and instruments Metrics are measurements of the router's behavior that can be exported and monitored. Different kinds of metrics include histograms, gauges, and counts. -Metrics can be consumed by _exporters_. See [Metrics exporters](./exporters/metrics/overview) for an overview of supported exporters. +Metrics can be consumed by _exporters_. See [Metrics exporters](/router/configuration/telemetry/exporters/metrics/overview) for an overview of supported exporters. An individual metric is called an _instrument_. Example instruments of the router include: @@ -112,11 +106,11 @@ An individual metric is called an _instrument_. Example instruments of the route * Histogram of request durations * Number of in-flight requests -See [Instruments](./instrumentation/instruments) for an overview of available instruments and a guide for configuring and customizing instruments. +See [Instruments](/router/configuration/telemetry/instrumentation/instruments) for an overview of available instruments and a guide for configuring and customizing instruments. ### Traces and spans -Traces monitor the flow of a request through the router. A trace is composed of [**spans**](./instrumentation/spans). A span captures a request's duration as it flows through the router request lifecycle. Spans may include contextual information about the request, such as the HTTP status code, or the name of the subgraph being queried. +Traces monitor the flow of a request through the router. A trace is composed of [**spans**](/router/configuration/telemetry/instrumentation/spans). A span captures a request's duration as it flows through the router request lifecycle. Spans may include contextual information about the request, such as the HTTP status code, or the name of the subgraph being queried. Examples of spans include: @@ -124,7 +118,7 @@ Examples of spans include: * `supergraph` - Wraps a request once GraphQL parsing has taken place * `subgraph` - Wraps a request to a subgraph. -Traces are consumed via [tracing exporters](./exporters/tracing/overview). +Traces are consumed via [tracing exporters](/router/configuration/telemetry/exporters/tracing/overview). ## Router telemetry exporters @@ -137,7 +131,7 @@ The router exports its collected telemetry in formats compatible with industry-s * Jaeger * Zipkin -For more information, see [logging exporters](./exporters/logging/overview), [metrics exporters](./exporters/metrics/overview), and [tracing exporters](./exporters/tracing/overview). +For more information, see [logging exporters](/router/configuration/telemetry/exporters/logging/overview), [metrics exporters](/router/configuration/telemetry/exporters/metrics/overview), and [tracing exporters](/router/configuration/telemetry/exporters/tracing/overview). ## Router telemetry attributes @@ -149,11 +143,11 @@ Example attributes include: * GraphQL operation name * Subgraph name -You can use [standard attributes](./instrumentation/standard-attributes) or [selectors](./instrumentation/selectors) as span attributes. +You can use [standard attributes](/router/configuration/telemetry/instrumentation/standard-attributes) or [selectors](/router/configuration/telemetry/instrumentation/selectors) as span attributes. -[Custom attributes for spans](./instrumentation/spans/#attributes) require a GraphOS [Dedicated or Enterprise plan](https://www.apollographql.com/pricing#observability). +[Custom attributes for spans](/router/configuration/telemetry/instrumentation/spans/#attributes) require a GraphOS [Dedicated or Enterprise plan](https://www.apollographql.com/pricing#observability). diff --git a/docs/source/executing-operations/defer-support.mdx b/docs/source/routing/operations/defer.mdx similarity index 69% rename from docs/source/executing-operations/defer-support.mdx rename to docs/source/routing/operations/defer.mdx index 0e6c4d76bc..7a21d412bb 100644 --- a/docs/source/executing-operations/defer-support.mdx +++ b/docs/source/routing/operations/defer.mdx @@ -35,11 +35,122 @@ To respond incrementally, the router uses a multipart-encoded HTTP response. To The router's `@defer` support is compatible with all [federation-compatible subgraph libraries](/federation/building-supergraphs/supported-subgraphs/), because the deferring logic exists entirely within the router itself. -### Basics of `@defer` +## Which fields can my router defer? -To learn the basics of the `@defer` directive and how you can use it with your supergraph, first read [Deferring query response data with GraphOS](/graphos/operations/defer). +Your router can defer the following fields in your schema: -The remainder of this article covers the router's defer implementation in greater depth. +- Root fields of the `Query` type (along with their subfields) +- Fields of any entity type (along with their subfields) + - Deferring entity fields is extremely powerful but requires some setup if you aren't using entities already. This is covered in more detail [below](#entity-fields). + +See below for more information on each of these. + +### `Query` fields + +Your router can defer any field of your schema's `Query` type, along with any subfields of those fields: + +```graphql +query GetUsersAndDeferProducts { + users { + id + } + # highlight-start + ... @defer { + products { + id + } + } + # highlight-end +} +``` + +With the query above, the router first returns a list of `User` IDs, then later completes the response with a list of `Product` IDs. + +### Entity fields + +Your router supports deferring fields of the special object types in your supergraph called entities. + +Entities are object types that often define their fields across multiple subgraphs (but they don't have to). You can identify an entity by its use of the `@key` directive. In the example subgraph schemas below, the `Product` type is an entity: + + + +```graphql title="Products subgraph" +type Product @key(fields: "id") { + id: ID! + name: String! + price: Int! +} + +type Query { + topProducts: [Product!]! +} +``` + +```graphql title="Reviews subgraph" +type Product @key(fields: "id") { + id: ID! + reviews: [Review!]! +} + +type Review { + score: Int! +} +``` + + + +Entities are query entry points into your subgraphs, and this is what enables your router to defer their fields: the router can send a followup query to a subgraph to fetch any entity fields that it doesn't fetch initially. + +Here's an example query that defers entity fields using the subgraphs above: + +```graphql +query GetProductsAndDeferReviews { + topProducts { + id + name + # highlight-start + ... @defer { + reviews { + score + } + } + # highlight-end + } +} +``` + +To handle this query, the router first resolves and returns a list of `Product` objects with their IDs and names. Later, the router completes the response by returning review scores for each of those products. + + + +It doesn't matter which subgraph defines a particular entity field! Queries can defer entity fields that are defined across any number of different subgraphs. + + + +### Defining entities in your subgraphs + +If your subgraphs don't yet include any entities, you need to define some before clients can start deferring their fields in queries. + +To learn about creating entities, see [this guide](/graphos/schema-design/federated-schemas/entities). + +## Requirements for `@defer` + +To use `@defer` successfully, your supergraph and its clients must meet the requirements listed below. These requirements are divided between [general requirements](#general-requirements) (requirements for using `@defer` at all) and [entity-specific requirements](#entity-specific-requirements) (additional requirements for using `@defer` with entity fields). + +### General requirements + +- Clients must support receiving deferred query responses as multipart HTTP responses. + - This functionality is currently supported in Apollo Client for [Web](/react/data/defer) and [Kotlin (experimental)](/kotlin/fetching/defer). +- Your supergraph must be one of: + - A [cloud supergraph](/graphos/routing/cloud#cloud-supergraphs) + - A [self-hosted supergraph](/graphos/routing/self-hosted#self-hosted-supergraphs) running the [GraphOS Router](/graphos/routing/about-router) + +### Entity-specific requirements + +- Your subgraphs must each use a [subgraph-compatible GraphQL server library](/graphos/reference/federation/compatible-subgraphs). +- You must [define one or more entities](/graphos/schema-design/federated-schemas/entities/intro#defining-an-entity) in your subgraph schemas. +- Each subgraph must define a [reference resolver](/graphos/schema-design/federated-schemas/entities/intro#2-define-a-reference-resolver) for each of its entities (or implement the corresponding functionality in your chosen subgraph library). + - This is what enables the router to directly access entity fields with followup sub-queries. ## Executing a `@defer` query @@ -56,7 +167,7 @@ Accept: multipart/mixed;deferSpec=20220824, application/json ## How does the router defer fields? -As discussed in [this article](/graphos/operations/defer/#which-fields-can-my-router-defer), the router can defer the following fields in your schema: +As discussed in [this section](#which-fields-can-my-router-defer), the router can defer the following fields in your schema: - Root fields of the `Query` type (along with their subfields) - Fields of any entity type (along with their subfields) @@ -274,7 +385,7 @@ The router supports the `@defer` directive as it's documented in [these edits to ## Disabling `@defer` -Defer support is enabled in the router by default. To _disable_ support, add `defer_support: false` to your router's [YAML config file](../configuration/overview/#yaml-config-file) under the `supergraph` key: +Defer support is enabled in the router by default. To _disable_ support, add `defer_support: false` to your router's [YAML config file](/router/configuration/overview/#yaml-config-file) under the `supergraph` key: ```yaml title="router.yaml" supergraph: diff --git a/docs/source/executing-operations/file-uploads.mdx b/docs/source/routing/operations/file-upload.mdx similarity index 99% rename from docs/source/executing-operations/file-uploads.mdx rename to docs/source/routing/operations/file-upload.mdx index 7b488fb28e..9170a22a1e 100644 --- a/docs/source/executing-operations/file-uploads.mdx +++ b/docs/source/routing/operations/file-upload.mdx @@ -286,7 +286,7 @@ Custom clients can be implemented following the [spec documentation](https://git Without additional security, HTTP multipart requests can be exploited as part of [cross-site request forgery](https://owasp.org/www-community/attacks/csrf) (CSRF) attacks. -The GraphOS Router already has a mechanism to prevent these types of attacks, which is enabled by default. You should verify that your router hasn't disabled this mechanism before using file uploads. See [Cross-Site Request Forgery Prevention](../configuration/csrf) for details. +The GraphOS Router already has a mechanism to prevent these types of attacks, which is enabled by default. You should verify that your router hasn't disabled this mechanism before using file uploads. See [Cross-Site Request Forgery Prevention](/router/configuration/csrf) for details. ## Metrics for file uploads diff --git a/docs/source/routing/operations/index.mdx b/docs/source/routing/operations/index.mdx new file mode 100644 index 0000000000..96f2310f06 --- /dev/null +++ b/docs/source/routing/operations/index.mdx @@ -0,0 +1,11 @@ +--- +title: Real-Time Operations +subtitle: Configure the router for real-time operations +description: Configure the Apollo GraphOS Router to support real-time operations, including subscriptions, defer directive, and file uploads. +--- + +Responsive applications rely on the router to handle operations in real time. You can configure to support various real-time operations: + +- [**Subscriptions**](/graphos/routing/operations/subscriptions) - support GraphQL subscription operations +- [**Defer**](/graphos/routing/operations/defer) - use the `@defer` directive to enable incremental delivery of response data +- [**File Uploads**](/graphos/routing/operations/file-upload) - upload files to the router using multipart HTTP requests diff --git a/docs/source/routing/operations/subscriptions/api-gateway.mdx b/docs/source/routing/operations/subscriptions/api-gateway.mdx new file mode 100644 index 0000000000..6c49d88679 --- /dev/null +++ b/docs/source/routing/operations/subscriptions/api-gateway.mdx @@ -0,0 +1,100 @@ +--- +title: Enabling HTTP Subscriptions with the GraphOS Router and an API Gateway +subtitle: Enable HTTP multipart subscriptions when using an API gateway in front of the router +description: Enable HTTP multipart subscriptions when using an API gateway in front of the router. +published: 2024-03-11 +id: TN0047 +tags: [router] +redirectFrom: + - /technotes/TN0047-using-http-subscriptions-api-gateway/ +--- + +Learn how to configure an API gateway to support HTTP multipart subscriptions with the GraphOS Router. + +Organizations can require their APIsโ€”including [the router](/graphos/routing/router-api-gateway-comparison)โ€”to be fronted by an API gateway. API gateways often aren't configured to support [subscriptions over HTTP multipart](/graphos/routing/operations/subscriptions#http-callback-setup): API gateways by default usually buffer HTTP responses, but subscriptions over HTTP multipart require multipart responses to be streamed, not buffered. + +The rest of this article describes how to configure API gateways from different vendors to stream and not buffer HTTP responses, therefore supporting subscriptions over HTTP multipart. + + + +## Azure API Management (APIM) + +By default, an HTTP API endpoint in APIM buffers each response from a downstream service, where the endpoint must receive all chunks of an HTTP response before it sends the response to the client. + +To enable HTTP subscriptions, the `forward-request` policy on the `backend` must be updated with `buffer-response="false"`. This configures the HTTP API endpoint to send the chunks of a response to the requesting client as they are received. + +```xml + + + + + +``` + + + +For more information, see the [Azure API Management policy reference - forward-request](https://learn.microsoft.com/en-us/azure/api-management/forward-request-policy#attributes). + + + + + +## Google Apigee + +By default, an HTTP API endpoint in Apigee buffers each response from a downstream service, where the endpoint must receive all chunks of an HTTP response before it sends the response to the client. + +To enable HTTP subscriptions, the `response.streaming.enabled` property must be set to `true` in both your `ProxyEndpoint` and `TargetEndpoint` definitions in the proxy bundle. This configures the HTTP API endpoint to send the chunks of a response to the requesting client as they are received. + +```xml + + + http://mocktarget.apigee.net + + true + + + +``` + +```xml + + + /v1/weather + + true + + + +``` + + + +For more information, see [Streaming requests and responses in the Apigee documentation](https://cloud.google.com/apigee/docs/api-platform/develop/enabling-streaming?hl=en). + + + +## Mulesoft + + + +### Flex Gateway + +Streaming of HTTP multipart is supported out of the box with no additional configuration required. + + + +### Proxy (Mule 4, CloudHub 2.0) + +Streaming of HTTP multipart isn't supported. Use Flex Gateway instead. + +## Kong + +Streaming of HTTP multipart is supported out of the box with no additional configuration required. + + + +## AWS API Gateway + +AWS API Gateway doesn't support streaming of HTTP data. + +A possible workaround is to use a Lambda expression which does support streaming. To learn more, see [AWS Lambda response streaming](https://aws.amazon.com/blogs/compute/introducing-aws-lambda-response-streaming/). diff --git a/docs/source/executing-operations/subscription-callback-protocol.mdx b/docs/source/routing/operations/subscriptions/callback-protocol.mdx similarity index 98% rename from docs/source/executing-operations/subscription-callback-protocol.mdx rename to docs/source/routing/operations/subscriptions/callback-protocol.mdx index 0f4c3e743c..04df169acd 100644 --- a/docs/source/executing-operations/subscription-callback-protocol.mdx +++ b/docs/source/routing/operations/subscriptions/callback-protocol.mdx @@ -8,7 +8,7 @@ This reference describes a protocol for GraphQL servers (or **subgraphs**) to se For routers with many simultaneous open subscriptions, this protocol scales better than WebSocket-based protocols, which require long-lasting open connections. -The GraphOS Router provides [support for this protocol](./subscription-support/#http-callback-setup) as part of its support for federated subscriptions: +The GraphOS Router provides [support for this protocol](/router/executing-operations/subscription-support/#http-callback-setup) as part of its support for federated subscriptions: ```mermaid sequenceDiagram diff --git a/docs/source/executing-operations/subscription-support.mdx b/docs/source/routing/operations/subscriptions/index.mdx similarity index 95% rename from docs/source/executing-operations/subscription-support.mdx rename to docs/source/routing/operations/subscriptions/index.mdx index 73bc205ea5..75cebe5e2d 100644 --- a/docs/source/executing-operations/subscription-support.mdx +++ b/docs/source/routing/operations/subscriptions/index.mdx @@ -5,15 +5,9 @@ description: Configure your router to support GraphQL subscriptions, enabling cl minVersion: 1.22.0 --- - - -**For self-hosted routers, subscription support is an [Enterprise feature](../enterprise-features/).** +**For self-hosted routers, subscription support is an [Enterprise feature](/router/enterprise-features/).** Subscription support is also available for cloud routers with a GraphOS Serverless or Dedicated plan. For cloud router subscription information, refer to [the cloud-specific docs](/graphos/operations/subscriptions). @@ -60,9 +54,9 @@ Whenever your router updates its supergraph schema at runtime, it terminates all Before you add `Subscription` fields to your subgraphs, do all of the following in the order shown to prevent schema composition errors: -1. Update your router instances to version `1.22.0` or later. [Download the latest version.](../quickstart/) +1. Update your router instances to version `1.22.0` or later. [Download the latest version.](/router/quickstart/) - Previous versions of the router don't support subscription operations. -1. Make sure your router is [connected to a GraphOS Enterprise organization](../enterprise-features/#enabling-enterprise-features). +1. Make sure your router is [connected to a GraphOS Enterprise organization](/router/enterprise-features/#enabling-enterprise-features). - Subscription support is an Enterprise feature of self-hosted routers. 1. **If you compose your router's supergraph schema with GraphOS** (instead of with the Rover CLI), [update your build pipeline](/graphos/graphs/updating#2-update-your-build-pipeline) to use Apollo Federation 2.4 or later. - Previous versions of Apollo Federation don't support subscription operations. @@ -88,7 +82,7 @@ After you complete these prerequisites, you can safely [configure your router](# ## Router setup -After completing all [prerequisites](#prerequisites), in your router's [YAML config file](../configuration/overview/#yaml-config-file), you configure how the router communicates with each of your subgraphs when executing GraphQL subscriptions. +After completing all [prerequisites](#prerequisites), in your router's [YAML config file](/router/configuration/overview/#yaml-config-file), you configure how the router communicates with each of your subgraphs when executing GraphQL subscriptions. The router supports two popular [WebSocket protocols](#websocket-setup) for subscriptions, and it also provides support for an [HTTP-callback-based protocol](#http-callback-setup). Your router must use whichever protocol is expected by each subgraph. @@ -152,7 +146,7 @@ The router provides support for receiving subgraph subscription events via HTTP - The router doesn't need to maintain a persistent connection for each distinct subscription. - You can publish events directly to the router from a pubsub system, instead of routing those events through the subgraph. -Callback mode requires your subgraph library to support the router's [HTTP callback protocol](./subscription-callback-protocol/). +Callback mode requires your subgraph library to support the router's [HTTP callback protocol](/router/executing-operations/subscription-callback-protocol/). @@ -340,7 +334,7 @@ content-type: application/json This example subscription only emits three events and then directly closes the connection. -For more information on this multipart HTTP subscription protocol, see [this article](./subscription-multipart-protocol/). +For more information on this multipart HTTP subscription protocol, see [this article](/router/executing-operations/subscription-multipart-protocol/). ## Subscription deduplication @@ -386,7 +380,7 @@ Whenever your router's supergraph schema is updated, **the router terminates all Your router's supergraph schema is updated in the following cases: - Your router regularly polls GraphOS for its supergraph schema, and an updated schema becomes available. -- Your router obtains its supergraph schema from a local file, which it watches for updates if the [`--hot-reload` option](../configuration/overview#--hr----hot-reload) is set. +- Your router obtains its supergraph schema from a local file, which it watches for updates if the [`--hot-reload` option](/router/configuration/overview#--hr----hot-reload) is set. When the router terminates subscriptions this way, it sends the following as a final response payload to all active subscribing clients: @@ -407,7 +401,7 @@ A client that receives this `SUBSCRIPTION_SCHEMA_RELOAD` error code can reconnec ### WebSocket auth support -By default, if you've configured your router to [propagate](../configuration/header-propagation/) HTTP `Authorization` headers to your subgraph, then the router automatically sets corresponding `connectionParams` when initiating a WebSocket connection to that subgraph. +By default, if you've configured your router to [propagate](/graphos/routing/header-propagation/) HTTP `Authorization` headers to your subgraph, then the router automatically sets corresponding `connectionParams` when initiating a WebSocket connection to that subgraph. For example, when your router sends the [`connection_init` message](https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md#connectioninit) to a subgraph, it includes the value of the `Authorization` header via the following payload: @@ -419,7 +413,7 @@ For example, when your router sends the [`connection_init` message](https://gith } ``` -To specify a custom payload for the`connection_init` message, you can write a [Rhai script](../customizations/rhai/) and use the `context` directly: +To specify a custom payload for the`connection_init` message, you can write a [Rhai script](/graphos/routing/customization/rhai/) and use the `context` directly: ```rhai fn subgraph_service(service, subgraph) { diff --git a/docs/source/executing-operations/subscription-multipart-protocol.mdx b/docs/source/routing/operations/subscriptions/multipart-protocol.mdx similarity index 98% rename from docs/source/executing-operations/subscription-multipart-protocol.mdx rename to docs/source/routing/operations/subscriptions/multipart-protocol.mdx index 6dad6feaf2..53f51ec5a2 100644 --- a/docs/source/executing-operations/subscription-multipart-protocol.mdx +++ b/docs/source/routing/operations/subscriptions/multipart-protocol.mdx @@ -4,7 +4,7 @@ subtitle: Enable clients to receive real-time updates via multipart HTTP protoco description: Enable real-time updates via multipart HTTP protocol for GraphQL subscriptions with the GraphOS Router. Learn about execution, heartbeats, and error handling. --- -To execute GraphQL subscription operations on the GraphOS Router, client apps do _not_ communicate over WebSocket. Instead, they use **HTTP with multipart responses**. This multipart protocol is built on the same [Incremental Delivery over HTTP](https://github.com/graphql/graphql-over-http/blob/main/rfcs/IncrementalDelivery.md) spec that the GraphOS Router uses to support [the `@defer` directive](./defer-support/). +To execute GraphQL subscription operations on the GraphOS Router, client apps do _not_ communicate over WebSocket. Instead, they use **HTTP with multipart responses**. This multipart protocol is built on the same [Incremental Delivery over HTTP](https://github.com/graphql/graphql-over-http/blob/main/rfcs/IncrementalDelivery.md) spec that the GraphOS Router uses to support [the `@defer` directive](/router/executing-operations/defer-support/). Use this reference if you're adding protocol support to a new GraphQL client library. [Apollo Client](/react/data/subscriptions#http), [Apollo Kotlin](/kotlin/essentials/subscriptions#configuring-http-subscriptions), and [Apollo iOS](/ios/fetching/subscriptions#http) all support this protocol. Apollo Client also provides network adapters for the [Relay](/react/data/subscriptions#relay) and [urql](/react/data/subscriptions#urql) libraries. diff --git a/docs/source/configuration/distributed-caching.mdx b/docs/source/routing/performance/caching/distributed.mdx similarity index 83% rename from docs/source/configuration/distributed-caching.mdx rename to docs/source/routing/performance/caching/distributed.mdx index fca1123ae1..2af986512b 100644 --- a/docs/source/configuration/distributed-caching.mdx +++ b/docs/source/routing/performance/caching/distributed.mdx @@ -4,24 +4,16 @@ subtitle: Configure Redis-backed caching for query plans and APQ description: Distributed caching for GraphOS Router with GraphOS Enterprise. Configure a Redis-backed cache for query plans and automatic persisted queries (APQ). --- -import RedisTLS from '../../shared/redis-tls.mdx' - - - -If you have multiple GraphOS Router instances, those instances can share a Redis-backed cache for their query plans and automatic persisted queries (APQ). This means that if _any_ of your router instances caches a particular value, _all_ of your instances can look up that value to significantly improve responsiveness. For more details on query plans and APQ, see the article on [in-memory caching](./in-memory-caching). +If you have multiple GraphOS Router instances, those instances can share a Redis-backed cache for their query plans and automatic persisted queries (APQ). This means that if _any_ of your router instances caches a particular value, _all_ of your instances can look up that value to significantly improve responsiveness. For more details on query plans and APQ, see the article on [in-memory caching](/router/configuration/in-memory-caching). ## Prerequisites To use this feature: - You must have a Redis cluster (or single instance) that your router instances can communicate with. -- You must have a [GraphOS Enterprise plan](https://www.apollographql.com/pricing/) and [connect your router to GraphOS](./overview/#environment-variables). +- You must have a [GraphOS Enterprise plan](https://www.apollographql.com/pricing/) and [connect your router to GraphOS](/router/configuration/overview/#environment-variables). ## How it works @@ -89,13 +81,13 @@ or, if configured with multiple URLs: -In your router's YAML config file, **you should specify your Redis URLs via environment variables and [variable expansion](./overview#variable-expansion)**. This prevents your Redis URLs from being committed to version control, which is especially dangerous if they include authentication information like a username and/or password. +In your router's YAML config file, **you should specify your Redis URLs via environment variables and [variable expansion](/router/configuration/overview#variable-expansion)**. This prevents your Redis URLs from being committed to version control, which is especially dangerous if they include authentication information like a username and/or password. ### Distributed query plan caching -To enable distributed caching of query plans, add the following to your router's [YAML config file](./overview/#yaml-config-file): +To enable distributed caching of query plans, add the following to your router's [YAML config file](/router/configuration/overview/#yaml-config-file): ```yaml title="router.yaml" supergraph: @@ -111,7 +103,7 @@ All query plan cache entries will be prefixed with `plan.` within the distribute ### Distributed APQ caching -To enable distributed caching of automatic persisted queries (APQ), add the following to your router's [YAML config file](./overview/#yaml-config-file): +To enable distributed caching of automatic persisted queries (APQ), add the following to your router's [YAML config file](/router/configuration/overview/#yaml-config-file): ```yaml title="router.yaml" apq: @@ -127,7 +119,7 @@ All APQ cache entries will be prefixed with `apq` followed by a null byte charac ### Common Redis configuration -Redis configuration is done in the same way for APQ caching, query plan caching and [entity caching](./entity-caching). +Redis configuration is done in the same way for APQ caching, query plan caching and [entity caching](/router/configuration/entity-caching). ```yaml title="router.yaml" supergraph: @@ -161,7 +153,23 @@ When using the same Redis instance for multiple purposes, the `namespace` option ### TLS - +For Redis TLS connections, you can set up a client certificate or override the root certificate authority by configuring `tls` in your router's [YAML config file](https://www.apollographql.com/docs/router/overview/#yaml-config-file). For example: + +```yaml +apq: + router: + cache: + redis: + urls: [ "rediss://redis.example.com:6379" ] + #highlight-start + tls: + certificate_authorities: ${file./path/to/ca.crt} + client_authentication: + certificate_chain: ${file./path/to/certificate_chain.pem} + key: ${file./path/to/key.pem} + #highlight-end +``` + ### Required to start diff --git a/docs/source/configuration/entity-caching.mdx b/docs/source/routing/performance/caching/entity.mdx similarity index 94% rename from docs/source/configuration/entity-caching.mdx rename to docs/source/routing/performance/caching/entity.mdx index 4f898ecdbc..218e6bd12a 100644 --- a/docs/source/configuration/entity-caching.mdx +++ b/docs/source/routing/performance/caching/entity.mdx @@ -5,12 +5,6 @@ description: Subgraph entity caching for GraphOS Router with GraphOS Enterprise. minVersion: 1.40.0 --- - - @@ -76,13 +70,13 @@ Follow this guide to enable and configure entity caching in the GraphOS Router. To use entity caching in the GraphOS Router, you must set up: - A Redis instance or cluster that your router instances can communicate with -- A [GraphOS Enterprise plan](https://www.apollographql.com/pricing/) that [connects your router to GraphOS](./overview/#environment-variables). +- A [GraphOS Enterprise plan](https://www.apollographql.com/pricing/) that [connects your router to GraphOS](/router/configuration/overview/#environment-variables). ### Configure router for entity caching In `router.yaml`, configure `preview_entity_cache`: - Enable entity caching globally. -- Configure Redis using the same conventions described in [distributed caching](./distributed-caching#redis-url-configuration). +- Configure Redis using the same conventions described in [distributed caching](/router/configuration/distributed-caching#redis-url-configuration). - Configure entity caching per subgraph, with overrides per subgraph for disabling entity caching and TTL. For example: @@ -375,7 +369,7 @@ The router implements the following sequence to determine whether a particular q ### Observability -The router supports a [`cache` selector](./telemetry/instrumentation/selectors#subgraph) in telemetry for the subgraph service. The selector returns the number of cache hits or misses by an entity for a subgraph request. +The router supports a [`cache` selector](/router/configuration/telemetry/instrumentation/selectors#subgraph) in telemetry for the subgraph service. The selector returns the number of cache hits or misses by an entity for a subgraph request. ## Spans @@ -451,7 +445,7 @@ If some entities were obtained from the cache, but the subgraphs that provided t ### Authorization and entity caching -When used alongside the router's [authorization directives](./authorization), cache entries are separated by authorization context. If a query contains fields that need a specific scope, the requests providing that scope have different cache entries from those not providing the scope. This means that data requiring authorization can still be safely cached and even shared across users, without needing invalidation when a user's roles change because their requests are automatically directed to a different part of the cache. +When used alongside the router's [authorization directives](/router/configuration/authorization), cache entries are separated by authorization context. If a query contains fields that need a specific scope, the requests providing that scope have different cache entries from those not providing the scope. This means that data requiring authorization can still be safely cached and even shared across users, without needing invalidation when a user's roles change because their requests are automatically directed to a different part of the cache. ### Schema updates and entity caching diff --git a/docs/source/configuration/in-memory-caching.mdx b/docs/source/routing/performance/caching/in-memory.mdx similarity index 87% rename from docs/source/configuration/in-memory-caching.mdx rename to docs/source/routing/performance/caching/in-memory.mdx index e90f6c1d3a..fbadf23a4d 100644 --- a/docs/source/configuration/in-memory-caching.mdx +++ b/docs/source/routing/performance/caching/in-memory.mdx @@ -4,12 +4,6 @@ subtitle: Configure router caching for query plans and automatic persisted queri description: Configure in-memory caching for improved performance in Apollo GraphOS Router or Apollo Router Core. Configure query plans and automatic persisted queries caching. --- - - Both GraphOS Router and Apollo Router Core use an in-memory LRU cache to store the following data: - [Generated query plans](#caching-query-plans) @@ -20,7 +14,7 @@ You can configure certain caching behaviors for generated query plans and APQ (b -If you have a GraphOS Enterprise plan, you can also configure a Redis-backed _distributed_ cache that enables multiple router instances to share cached values. For details, see [Distributed caching in the GraphOS Router](./distributed-caching/). +If you have a GraphOS Enterprise plan, you can also configure a Redis-backed _distributed_ cache that enables multiple router instances to share cached values. For details, see [Distributed caching in the GraphOS Router](/router/configuration/distributed-caching/). @@ -34,7 +28,7 @@ Whenever your router receives an incoming GraphQL operation, it generates a [que By caching previously generated query plans, your router can _skip_ generating them _again_ if a client later sends the exact same operation. This improves your router's responsiveness. -The GraphOS Router enables query plan caching by default. In your router's [YAML config file](./overview/#yaml-config-file), you can configure the maximum number of query plan entries in the cache like so: +The GraphOS Router enables query plan caching by default. In your router's [YAML config file](/router/configuration/overview/#yaml-config-file), you can configure the maximum number of query plan entries in the cache like so: ```yaml title="router.yaml" supergraph: @@ -61,7 +55,7 @@ supergraph: warmed_up_queries: 100 ``` -(In addition, the router can use the contents of the [persisted query list](./persisted-queries) to prewarm the cache. By default, it does this when loading a new schema but not on startup; you can [configure](./persisted-queries#persisted-queries#experimental_prewarm_query_plan_cache) it to change either of these defaults.) +(In addition, the router can use the contents of the [persisted query list](/router/configuration/persisted-queries) to prewarm the cache. By default, it does this when loading a new schema but not on startup; you can [configure](/router/configuration/persisted-queries#persisted-queries#experimental_prewarm_query_plan_cache) it to change either of these defaults.) To get more information on the planning and warm-up process use the following metrics (where `` can be `redis` for distributed cache or `memory`): @@ -112,7 +106,7 @@ Because the router's role differs between these two interactions, you configure ### APQ with clients -The router enables APQ caching for client operations by default. In your router's [YAML config file](./overview/#yaml-config-file), you can configure the maximum number of APQ entries in the cache like so: +The router enables APQ caching for client operations by default. In your router's [YAML config file](/router/configuration/overview/#yaml-config-file), you can configure the maximum number of APQ entries in the cache like so: ```yaml title="router.yaml" apq: @@ -133,7 +127,7 @@ apq: By default, the router does _not_ use APQ when sending queries to its subgraphs. -In your router's [YAML config file](./overview/#yaml-config-file), you can configure this APQ support with a combination of global and per-subgraph settings: +In your router's [YAML config file](/router/configuration/overview/#yaml-config-file), you can configure this APQ support with a combination of global and per-subgraph settings: ```yaml title="router.yaml" apq: diff --git a/docs/source/routing/performance/caching/index.mdx b/docs/source/routing/performance/caching/index.mdx new file mode 100644 index 0000000000..8a004e82cf --- /dev/null +++ b/docs/source/routing/performance/caching/index.mdx @@ -0,0 +1,16 @@ +--- +title: Caching +subtitle: Accelerate query retrieval with GraphOS caching. +--- + +By default, GraphOS Router stores the following data in its in-memory cache to improve performance: + +- Generated query plans +- Automatic persisted queries (APQ) +- Introspection responses + +You can configure certain caching behaviors for generated query plans and APQ (but not introspection responses). For details, see In-memory caching in the Apollo Router. + +If you have a GraphOS Enterprise plan, you can configure a Redis-backed distributed cache that enables multiple router instances to share cached values. For details, see Distributed caching in GraphOS Router. + +You can configure a Redis-backed entity cache that enables a client query to retrieve cached entity data split between subgraph responses. For details, see subgraph entity caching in GraphOS Router. diff --git a/docs/source/executing-operations/query-batching.mdx b/docs/source/routing/performance/query-batching.mdx similarity index 97% rename from docs/source/executing-operations/query-batching.mdx rename to docs/source/routing/performance/query-batching.mdx index 739f68e1d6..50530f8797 100644 --- a/docs/source/executing-operations/query-batching.mdx +++ b/docs/source/routing/performance/query-batching.mdx @@ -87,7 +87,7 @@ batching: - There are limitations on the ability of the router to preserve batches from the client request into the subgraph requests. In particular, certain forms of queries will require data to be present before they are processed. Consequently, the router will only be able to generate batches from queries which are processed which don't contain such constraints. This may result in the router issuing multiple batches or requests. -- If [query deduplication](../configuration/traffic-shaping/#query-deduplication) or [entity caching](../configuration/entity-caching) are enabled, they will not apply to batched queries. Batching will take precedence over query deduplication and entity caching. Query deduplication and Entity caching will still be performed for non-batched queries. +- If [query deduplication](/router/configuration/traffic-shaping/#query-deduplication) or [entity caching](/router/configuration/entity-caching) are enabled, they will not apply to batched queries. Batching will take precedence over query deduplication and entity caching. Query deduplication and Entity caching will still be performed for non-batched queries. diff --git a/docs/source/routing/performance/query-planner-pools.mdx b/docs/source/routing/performance/query-planner-pools.mdx new file mode 100644 index 0000000000..e278a1e030 --- /dev/null +++ b/docs/source/routing/performance/query-planner-pools.mdx @@ -0,0 +1,34 @@ +--- +title: Query Planner Pools +subtitle: Run multiple query planners in parallel +minVersion: 1.44.0 +redirectFrom: + - /router/configuration/overview/#query-planner-pools +--- + + + +You can improve the performance of the router's query planner by configuring parallelized query planning. + +By default, the query planner plans one operation at a time. It plans one operation to completion before planning the next one. This serial planning can be problematic when an operation takes a long time to plan and consequently blocks the query planner from working on other operations. + +## Configuring query planner pools + +To resolve such blocking scenarios, you can enable parallel query planning. Configure it in `router.yaml` with `supergraph.query_planning.experimental_parallelism`: + +```yaml title="router.yaml" +supergraph: + query_planning: + experimental_parallelism: auto # number of available cpus +``` + +The value of `experimental_parallelism` is the number of query planners in the router's _query planner pool_. A query planner pool is a preallocated set of query planners from which the router can use to plan operations. The total number of pools is the maximum number of query planners that can run in parallel and therefore the maximum number of operations that can be worked on simultaneously. + +Valid values of `experimental_parallelism`: +- Any integer starting from `1` +- The special value `auto`, which sets the number of query planners equal to the number of available CPUs on the router's host machine + +The default value of `experimental_parallelism` is `1`. + +In practice, you should tune `experimental_parallelism` based on metrics and benchmarks gathered from your router. \ No newline at end of file diff --git a/docs/source/configuration/traffic-shaping.mdx b/docs/source/routing/performance/traffic-shaping.mdx similarity index 89% rename from docs/source/configuration/traffic-shaping.mdx rename to docs/source/routing/performance/traffic-shaping.mdx index adfbe3f8ad..19cc7db838 100644 --- a/docs/source/configuration/traffic-shaping.mdx +++ b/docs/source/routing/performance/traffic-shaping.mdx @@ -8,7 +8,7 @@ The GraphOS Router and Apollo Router Core provide various features to improve th ## Configuration -By default, the `traffic_shaping` plugin is enabled with [preset values](#preset-values). To override presets, add `traffic_shaping` to your [YAML config file](./overview/#yaml-config-file) like so: +By default, the `traffic_shaping` plugin is enabled with [preset values](#preset-values). To override presets, add `traffic_shaping` to your [YAML config file](/router/configuration/overview/#yaml-config-file) like so: ```yaml title="router.yaml" traffic_shaping: @@ -34,7 +34,6 @@ traffic_shaping: retry_percent: 0.2 # defines the proportion of available retries to the current number of tokens retry_mutations: false # allows retries on mutations. This should only be enabled if mutations are idempotent experimental_http2: enable # Configures HTTP/2 usage. Can be 'enable' (default), 'disable' or 'http2only' - dns_resolution_strategy: ipv4_then_ipv6 # Changes DNS resolution strategy for subgraph. ``` ### Preset values @@ -43,7 +42,6 @@ The preset values of `traffic_shaping` that's enabled by default: - `timeout: 30s` for all timeouts - `experimental_http2: enable` -- `dns_resolution_strategy: ipv4_then_ipv6` ## Client side traffic shaping @@ -88,7 +86,7 @@ traffic_shaping: -Since [deferred](../executing-operations/defer-support/#what-is-defer) fragments are separate requests, each fragment's request is individually subject to timeouts. +Since [deferred](/router/executing-operations/defer-support/#what-is-defer) fragments are separate requests, each fragment's request is individually subject to timeouts. @@ -106,7 +104,7 @@ batching: mode: batch_http_link ``` -For details, see [query batching for the router](../executing-operations/query-batching). +For details, see [query batching for the router](/router/executing-operations/query-batching). ## Subgraph traffic shaping @@ -188,23 +186,6 @@ traffic_shaping: -### DNS resolution strategy - -You can also change DNS resolution strategy applied to subgraphs's URL: -```yaml title="router.yaml" -traffic_shaping: - all: - dns_resolution_strategy: ipv4_then_ipv6 - -``` - -Possible strategies are: -* `ipv4_only` - Only query for `A` (IPv4) records. -* `ipv6_only` - Only query for `AAAA` (IPv6) records. -* `ipv4_and_ipv6` - Query for both `A` (IPv4) and `AAAA` (IPv6) records in parallel. -* `ipv6_then_ipv4` - Query for `AAAA` (IPv6) records first; if that fails, query for `A` (IPv4) records. -* `ipv4_then_ipv6`(default) - Query for `A` (IPv4) records first; if that fails, query for `AAAA` (IPv6) records. - ### Ordering Traffic shaping always executes these steps in the same order, to ensure a consistent behaviour. Declaration order in the configuration will not affect the runtime order: diff --git a/docs/source/routing/query-planning/native-query-planner.mdx b/docs/source/routing/query-planning/native-query-planner.mdx new file mode 100644 index 0000000000..7da2d5a099 --- /dev/null +++ b/docs/source/routing/query-planning/native-query-planner.mdx @@ -0,0 +1,79 @@ +--- +title: Native Query Planner +subtitle: Run the Rust-native query planner in GraphOS Router +minVersion: 1.49.0 +redirectFrom: + - /router/configuration/experimental_query_planner_mode + - /router/executing-operations/native-query-planner +--- + + + +Learn to run the GraphOS Router with the Rust-native query planner and improve your query planning performance and scalability. + +## Background about query planner implementations + +In v1.49.0 the router introduced a [query planner](/graphos/routing/about-router#query-planning) implemented natively in Rust. This native query planner improves the overall performance and resource utilization of query planning. It exists alongside the legacy JavaScript implementation that uses the V8 JavaScript engine, and it will eventually replace the legacy implementation. + +### Comparing query planner implementations + +As part of the effort to ensure correctness and stability of the new query planner, starting in v1.53.0 the router enables both the new and legacy planners and runs them in parallel to compare their results by default. After their comparison, the router discards the native query planner's results and uses only the legacy planner to execute requests. The native query planner uses a single thread in the cold path of the router. It has a bounded queue of ten queries. If the queue is full, the router simply does not run the comparison to avoid excessive resource consumption. + +## Configuring query planning + +You can configure the `experimental_query_planner_mode` option in your `router.yaml` to set the query planner to run. + +The `experimental_query_planner_mode` option has the following supported modes: + +- `new`- enables only the new Rust-native query planner +- `legacy` - enables only the legacy JavaScript query planner +- `both_best_effort` (default) - enables both new and legacy query planners for comparison. The legacy query planner is used for execution. + + + +## Optimize native query planner + + + +To run the native query planner with the best performance and resource utilization, configure your router with the following options: + +```yaml title="router.yaml" +experimental_query_planner_mode: new +``` + + + +In router v1.56, running the native query planner with the best performance and resource utilization also requires setting `experimental_introspection_mode: new`. + + + +Setting `experimental_query_planner_mode: new` not only enables native query planning and schema introspection, it also disables the V8 JavaScript runtime used by the legacy query planner. Disabling V8 frees up CPU and memory and improves native query planning performance. + +Additionally, to enable more optimal native query planning and faster throughput by reducing the size of queries sent to subgraphs, you can enable query fragment generation with the following option: + +```yaml title="router.yaml" +supergraph: + generate_query_fragments: true +``` + + + +Regarding [fragment reuse and generation](/router/configuration/overview#fragment-reuse-and-generation), in the future the `generate_query_fragments` option will be the only option for handling fragments. + + + +## Metrics for native query planner + +When running both query planners for comparison with `experimental_query_planner_mode: both_best_effort`, the following metrics track mismatches and errors: + +- `apollo.router.operations.query_planner.both` with the following attributes: + - `generation.is_matched` (bool) + - `generation.js_error` (bool) + - `generation.rust_error` (bool) + +- `apollo.router.query_planning.plan.duration` with the following attributes to differentiate between planners: + - `planner` (rust | js) + +## Limitations of native query planner + +The native query planner doesn't implement `@context`. This is planned to be implemented in a future router release. diff --git a/docs/source/routing/router-api-gateway-comparison.mdx b/docs/source/routing/router-api-gateway-comparison.mdx new file mode 100644 index 0000000000..7bc41176c0 --- /dev/null +++ b/docs/source/routing/router-api-gateway-comparison.mdx @@ -0,0 +1,115 @@ +--- +title: Does GraphOS Router Replace My API Gateway? +subtitle: How the GraphOS Router differs from API gateways +description: The GraphOS Router isn't based on URLs or REST endpoints, its a GraphQL-native solution to handle your clients API operations. +published: 2023-03-31 +id: TN0037 +tags: [federation, router, gateway] +redirectFrom: + - /technotes/TN0037-api-gateways/ +--- + +The GraphOS Router is a high-performant GraphQL gateway that supports [Apollo Federation](https://www.apollographql.com/docs/federation). It handles GraphQL requests that can then be resolved by many GraphQL subgraphs underneath. When comparing the router to other API technologies in the market today, a natural first comparison to draw is to API gateways. Tools like Kong or your cloud provider offer capabilities to secure, manage, and monitor your API endpoints. +These gateways usually live at the outermost edges of your companies infrastructure. Sometimes they are even required by your security team so that all inbound and outbound traffic flows through the same top layer of your tech stack. + +The key distinction of the router is that is not based on URLs or REST endpoints. The router is a GraphQL-native solution to handle your clients API operations. + + + +Apollo GraphQL and Kong have partnered to produce a joint paper that provides API practitioners with the tools they need to navigate the complex API landscape and drive successful digital experiences. Read more in the [blog post](https://www.apollographql.com/blog/leveraging-graphql-for-next-generation-api-platforms). + + + +## GraphQL native + +First, let's define what we mean by "GraphQL native." The GraphOS Router runs all the client operations against a [supergraph](/intro/platform/). +This means that requests processed by the router are not for any random service, but are restricted to what is defined and published by the GraphQL subgraphs for a given supergraph schema. +Subgraphs define the schema and capabilities they want to expose. A well-defined GraphQL schema does not just expose all the data available in a company, instead, a [demand-oriented schema](/graphos/schema-design/guides/demand-oriented-schema-design) gives clients access to all the operations they need to execute, but without over exposing your data. +Since subgraphs are also the ones that define their service capabilities, the router can be the central location to enforce standardized rules or policies that are declared by subgraphs, for example, [a directive-based authN/Z plugin](https://www.apollographql.com/blog/platform/financial-services/directive-based-authorization-for-financial-services/). + +```graphql +type Query { + bankAccounts: [BankAccount] @authenticated @hasRole(role: ADMIN) +} +``` + +API gateways (like Apigee, Mulesoft, or ones from AWS, Azure, or Google Cloud) usually have little understanding of all the services underneath them or what their capabilities are. They may have configuration options and rules that can apply to those services, but these are blanket rules that must be configured at the gateway level, not at the service definition. +If you wanted to apply a common rule across many services it would be up to the API gateway managers to configure, deploy, and apply that new rule to a set of services rather than the individual service teams. + +```yaml +# Mock gateway rules +gatewayConfig: + myCustomRule: + tags: [requiresAuth] + ruleToApply: validate-jwt-plugin + myOtherCustomRule: + URL: '/accounts' + ruleToApply: requires-admin-permissions-plugin +``` + +## Support for non-GraphQL APIs + +GraphQL is an innovative technology that give clients much more control over their operations and a common language for service teams to communicate. However, GraphQL usually is not the one and only API technology used by companies today. +If you need to have a common gateway to secure REST endpoints and GraphQL endpoints, the GraphOS Router can be a complimentary tool that lives underneath this higher-level API gateway. You can configure company-wide policies at the outermost edge layer, and anything else that is better defined as a GraphQL-specific policy can be managed by the router. +In addition, using a [defense-in-depth](https://csrc.nist.gov/glossary/term/defense_in_depth) security strategy reduces your companies risk, so having both an API gateway and router applying shared rules can lead to a more secure environment. + +```mermaid +graph LR + +subgraph Clients + Client1 + Client2 + Client3 +end + +subgraph Partners + Partner1 + Partner2 +end + +subgraph Edge + API-Gateway +end + +style Edge height:100%; + +subgraph GraphQL + Router + Subgraph1 + Subgraph2 +end + +subgraph Data Layer + REST1 + REST2 + gRPC1 + DB1 + DB2 +end + +Client1 --> API-Gateway +Client2 --> API-Gateway +Client3 --> API-Gateway +Partner1 --> API-Gateway +Partner2 --> API-Gateway +API-Gateway --> Router +API-Gateway --> REST1 +API-Gateway --> REST2 +Router --> Subgraph1 +Router --> Subgraph2 +Subgraph1 --> gRPC1 +Subgraph1 --> DB1 +Subgraph1 --> REST2 +Subgraph2 --> DB2 +``` + +## When to consider GraphOS Router + +If you are running a GraphQL API in production, and you want to be able to: + +- [Monitor your GraphQL operations](/graphos/platform/insights/field-usage) in a way that other telemetry tools don't support while [continuing support for existing APM tools](/graphos/reference/router/telemetry/metrics-exporters/overview) +- [Safely publish new schemas without introducing a breaking change](/graphos/platform/schema-management/checks) +- [Secure your GraphQL schema](https://www.apollographql.com/docs/router/configuration/authn-jwt) +- [Extend the GraphQL runtime with custom features](https://www.apollographql.com/docs/router/customizations/overview) + +And do all this with [minimal latency and scalable performance](https://www.apollographql.com/blog/announcement/backend/apollo-router-our-graphql-federation-runtime-in-rust) then consider adopting [GraphOS and the GraphOS Router](/graphos/) today! diff --git a/docs/source/configuration/authorization.mdx b/docs/source/routing/security/authorization.mdx similarity index 88% rename from docs/source/configuration/authorization.mdx rename to docs/source/routing/security/authorization.mdx index f31e4e4226..9ef9776743 100644 --- a/docs/source/configuration/authorization.mdx +++ b/docs/source/routing/security/authorization.mdx @@ -24,7 +24,7 @@ Services may have their own access controls, but enforcing authorization _in the clients -->|"โš ๏ธUnauthorized
      request"| router; ``` - - If every field in a particular subquery requires authorization, the router's [query planner](../customizations/overview#request-path) can _eliminate entire subgraph requests_ for unauthorized requests. For example, a request may have permission to view a particular user's posts on a social media platform but not have permission to view any of that user's personally identifiable information (PII). Check out [How it works](#how-it-works) to learn more. + - If every field in a particular subquery requires authorization, the router's [query planner](/router/customizations/overview#request-path) can _eliminate entire subgraph requests_ for unauthorized requests. For example, a request may have permission to view a particular user's posts on a social media platform but not have permission to view any of that user's personally identifiable information (PII). Check out [How it works](#how-it-works) to learn more. ```mermaid flowchart LR; @@ -38,7 +38,7 @@ Services may have their own access controls, but enforcing authorization _in the router -.->|"โŒ Unauthorized
      subquery"| serviceB; clients -->|"โš ๏ธ Partially authorized
      request"| router; ``` - - Also, [query deduplication](./traffic-shaping/#query-deduplication) groups requested fields based on their required authorization. Entire groups can be eliminated from the query plan if they don't have the correct authorization. + - Also, [query deduplication](/router/configuration/traffic-shaping/#query-deduplication) groups requested fields based on their required authorization. Entire groups can be eliminated from the query plan if they don't have the correct authorization. - **Declarative access rules**: You define access controls at the field level, and GraphOS [composes](#composition-and-federation) them across your services. These rules create graph-native governance without the need for an extra orchestration layer. @@ -80,7 +80,7 @@ The GraphOS Router provides access controls via **authorization directives** tha - The [`@requiresScopes`](#requiresscopes) directive allows granular access control through the scopes you define. - The [`@authenticated`](#authenticated) directive allows access to the annotated field or type for _authenticated requests only_. -- The [`@policy`](#policy) directive offloads authorization validation to a [Rhai script](../customizations/rhai/) or a [coprocessor](../customizations/coprocessor) and integrates the result in the router. It's useful when your authorization policies go beyond simple authentication and scopes. +- The [`@policy`](#policy) directive offloads authorization validation to a [Rhai script](/graphos/routing/customization/rhai/) or a [coprocessor](/router/customizations/coprocessor) and integrates the result in the router. It's useful when your authorization policies go beyond simple authentication and scopes. For example, imagine you're building a social media platform that includes a `Users` subgraph. You can use the [`@requiresScopes`](#requiresscopes) directive to declare that viewing other users' information requires the `read:user` scope: @@ -106,12 +106,12 @@ The router then enforces these directives on all incoming requests. -Only the GraphOS Router supports authorization directives—[`@apollo/gateway`](/federation/v1/gateway/) does _not_. Check out the [migration guide](../migrating-from-gateway/) if you'd like to use them. +Only the GraphOS Router supports authorization directives—[`@apollo/gateway`](/federation/v1/gateway/) does _not_. Check out the [migration guide](/router/migrating-from-gateway/) if you'd like to use them. Before using the authorization directives in your subgraph schemas, you must: -- Validate that your GraphOS Router uses version `1.29.1` or later and is [connected to your GraphOS Enterprise organization](../enterprise-features/#enabling-enterprise-features) +- Validate that your GraphOS Router uses version `1.29.1` or later and is [connected to your GraphOS Enterprise organization](/router/enterprise-features/#enabling-enterprise-features) - Include **[claims](#configure-request-claims)** in requests made to the router (for `@authenticated` and `@requiresScopes`) ### Configure request claims @@ -120,13 +120,13 @@ Claims are the individual details of a request's authentication and scope. They To provide the router with the claims it needs, you must either configure JSON Web Token (JWT) authentication or add an external coprocessor that adds claims to a request's context. In some cases (explained below), you may require both. -- **JWT authentication configuration**: If you configure [JWT authentication](./authn-jwt), the GraphOS Router [automatically adds a JWT token's claims](./authn-jwt#working-with-jwt-claims) to the request's context at the `apollo_authentication::JWT::claims` key. -- **Adding claims via coprocessor**: If you can't use JWT authentication, you can [add claims with a coprocessor](../customizations/coprocessor#adding-authorization-claims-via-coprocessor). Coprocessors let you hook into the GraphOS Router's request-handling lifecycle with custom code. -- **Augmenting JWT claims via coprocessor**: Your authorization policies may require information beyond what your JSON web tokens provide. For example, a token's claims may include user IDs, which you then use to look up user roles. For situations like this, you can [augment the claims](./authn-jwt#claim-augmentation-via-coprocessors) from your JSON web tokens with coprocessors. +- **JWT authentication configuration**: If you configure [JWT authentication](/router/configuration/authn-jwt), the GraphOS Router [automatically adds a JWT token's claims](/router/configuration/authn-jwt#working-with-jwt-claims) to the request's context at the `apollo_authentication::JWT::claims` key. +- **Adding claims via coprocessor**: If you can't use JWT authentication, you can [add claims with a coprocessor](/router/customizations/coprocessor#adding-authorization-claims-via-coprocessor). Coprocessors let you hook into the GraphOS Router's request-handling lifecycle with custom code. +- **Augmenting JWT claims via coprocessor**: Your authorization policies may require information beyond what your JSON web tokens provide. For example, a token's claims may include user IDs, which you then use to look up user roles. For situations like this, you can [augment the claims](/router/configuration/authn-jwt#claim-augmentation-via-coprocessors) from your JSON web tokens with coprocessors. ## Authorization directives -Authorization directives are turned on by default. To disable them, include the following in your router's [YAML config file](./overview/): +Authorization directives are turned on by default. To disable them, include the following in your router's [YAML config file](/router/configuration/overview/): ```yaml title="router.yaml" authorization: @@ -169,7 +169,7 @@ claims["scope"] = "scope1 scope2 scope3" -If the `apollo_authentication::JWT::claims` object holds scopes in another format, for example, an array of strings, or at a key other than `"scope"`, you can edit the claims with a [Rhai script](../customizations/rhai). +If the `apollo_authentication::JWT::claims` object holds scopes in another format, for example, an array of strings, or at a key other than `"scope"`, you can edit the claims with a [Rhai script](/graphos/routing/customization/rhai). The example below extracts an array of scopes from the `"roles"` claim and reformats them as a space-separated string. @@ -479,7 +479,7 @@ If _every_ requested field requires authentication and a request is unauthentica
      -The `@policy` directive marks fields and types as restricted based on authorization policies evaluated in a [Rhai script](../customizations/rhai/) or [coprocessor](../customizations/coprocessor). This enables custom authorization validation beyond authentication and scopes. It is useful when we need more complex policy evaluation than verifying the presence of a claim value in a list (example: checking specific values in headers). +The `@policy` directive marks fields and types as restricted based on authorization policies evaluated in a [Rhai script](/graphos/routing/customization/rhai/) or [coprocessor](/router/customizations/coprocessor). This enables custom authorization validation beyond authentication and scopes. It is useful when we need more complex policy evaluation than verifying the presence of a claim value in a list (example: checking specific values in headers). @@ -493,11 +493,11 @@ The `@policy` directive includes a `policies` argument that defines an array of @policy(policies: [["roles:support"]]) ``` -Using the `@policy` directive requires a [Supergraph plugin](../customizations/overview) to evaluate the authorization policies. This is useful to bridge router authorization with an existing authorization stack or link policy execution with lookups in a database. +Using the `@policy` directive requires a [Supergraph plugin](/router/customizations/overview) to evaluate the authorization policies. This is useful to bridge router authorization with an existing authorization stack or link policy execution with lookups in a database. An overview of how `@policy` is processed through the router's request lifecycle: -* At the [`RouterService` level](../customizations/overview#the-request-lifecycle), the GraphOS Router extracts the list of policies relevant to a request from the schema and then stores them in the request's context in `apollo_authorization::policies::required` as a map `policy -> null|true|false`. +* At the [`RouterService` level](/router/customizations/overview#the-request-lifecycle), the GraphOS Router extracts the list of policies relevant to a request from the schema and then stores them in the request's context in `apollo_authorization::policies::required` as a map `policy -> null|true|false`. * At the `SupergraphService` level, you must provide a Rhai script or coprocessor to evaluate the map. If the policy is validated, the script or coprocessor should set its value to `true` or otherwise set it to `false`. If the value is left to `null`, it will be treated as `false` by the router. Afterward, the router filters the requests' types and fields to only those where the policy is `true`. @@ -522,7 +522,7 @@ scalar federation__Policy directive @policy(policies: [[federation__Policy!]!]!) on OBJECT | FIELD_DEFINITION | INTERFACE | SCALAR | ENUM ``` -Using the `@policy` directive requires a [Supergraph plugin](../customizations/overview) to evaluate the authorization policies. You can do this with a [Rhai script](../customizations/rhai/) or [coprocessor](../customizations/coprocessor). Refer to the following [example use case](#example-policy-use-case) for more information. (Although a [native plugin](../customizations/native) can also evaluate authorization policies, we don't recommend using it.) +Using the `@policy` directive requires a [Supergraph plugin](/router/customizations/overview) to evaluate the authorization policies. You can do this with a [Rhai script](/graphos/routing/customization/rhai/) or [coprocessor](/router/customizations/coprocessor). Refer to the following [example use case](#example-policy-use-case) for more information. (Although a [native plugin](/router/customizations/native) can also evaluate authorization policies, we don't recommend using it.) #### Combining policies with `AND`/`OR` logic @@ -576,7 +576,7 @@ type Post { ``` -You can use a [coprocessor](../customizations/coprocessor) called at the Supergraph request stage to receive and execute the list of policies. +You can use a [coprocessor](/router/customizations/coprocessor) called at the Supergraph request stage to receive and execute the list of policies. If you configure your router like this: @@ -695,6 +695,7 @@ GraphOS's composition strategy for authorization directives is intentionally acc If a shared field uses different authorization directives across subgraphs, composition merges them using `AND` logic. For example, suppose the `me` query requires `@authenticated` in one subgraph and the `read:user` scope in another subgraph: + ```graphql title="Subgraph A" type Query { me: User @authenticated @@ -762,8 +763,8 @@ Refer to the section on [Combining policies with AND/OR logic](#combining-polici Using **OR** logic for shared directives simplifies schema updates. If requirements change suddenly, you don't need to update the directive in all subgraphs simultaneously. -#### Combining `AND`/`OR` logic with `@requiresScopes` +#### Combining `AND`/`OR` logic with `@requiresScopes` As with [combining scopes for a single use of [`@requiresScopes`](#combining-required-scopes-with-andor-logic), you can use nested arrays to introduce **AND** logic in a single subgraph: ```graphql title="Subgraph A" @@ -909,13 +910,13 @@ The response would include an `"UNAUTHORIZED_FIELD_OR_TYPE"` error at the `/post ## Query deduplication -You can enable [query deduplication](../configuration/traffic-shaping/#query-deduplication) in the router to reduce redundant requests to a subgraph. The router does this by buffering similar queries and reusing the result. +You can enable [query deduplication](/router/configuration/traffic-shaping/#query-deduplication) in the router to reduce redundant requests to a subgraph. The router does this by buffering similar queries and reusing the result. **Query deduplication takes authorization into account.** First, the router groups unauthenticated queries together. Then it groups authenticated queries by their required scope set. It uses these groups to execute queries efficiently when fulfilling requests. ## Introspection -Introspection is turned off in the router by default, [as is best production practice](https://www.apollographql.com/blog/graphql/security/why-you-should-disable-graphql-introspection-in-production/). If you've chosen to [enable it](./overview/#introspection), keep in mind that **authorization directives don't affect introspection**. All fields that require authorization remain visible. However, directives applied to fields _aren't_ visible. If introspection might reveal too much information about internal types, then be sure it hasn't been enabled in your router configuration. +Introspection is turned off in the router by default, [as is best production practice](https://www.apollographql.com/blog/graphql/security/why-you-should-disable-graphql-introspection-in-production/). If you've chosen to [enable it](/router/configuration/overview/#introspection), keep in mind that **authorization directives don't affect introspection**. All fields that require authorization remain visible. However, directives applied to fields _aren't_ visible. If introspection might reveal too much information about internal types, then be sure it hasn't been enabled in your router configuration. With introspection turned off, you can use GraphOS's [schema registry](/graphos/delivery/) to explore your supergraph schema and empower your teammates to do the same. If you want to completely remove fields from a graph rather than just preventing access (even with introspection on), consider building a [contract graph](/graphos/delivery/contracts/). diff --git a/docs/source/configuration/cors.mdx b/docs/source/routing/security/cors.mdx similarity index 98% rename from docs/source/configuration/cors.mdx rename to docs/source/routing/security/cors.mdx index 45e331f2ba..82e4c7ccf9 100644 --- a/docs/source/configuration/cors.mdx +++ b/docs/source/routing/security/cors.mdx @@ -13,7 +13,7 @@ description: Manage browser access to your Apollo GraphOS Router or Apollo Route
      -By default, the router enables _only_ GraphOS Studio to initiate browser connections to it. If your supergraph serves data to other browser-based applications, you need to do one of the following in the `cors` section of your router's [YAML config file](./overview/#yaml-config-file): +By default, the router enables _only_ GraphOS Studio to initiate browser connections to it. If your supergraph serves data to other browser-based applications, you need to do one of the following in the `cors` section of your router's [YAML config file](/router/configuration/overview/#yaml-config-file): * Add the origins of those web applications to the router's list of allowed `origins`. * Use this option if there is a known, finite list of web applications that consume your supergraph. diff --git a/docs/source/configuration/csrf.mdx b/docs/source/routing/security/csrf.mdx similarity index 95% rename from docs/source/configuration/csrf.mdx rename to docs/source/routing/security/csrf.mdx index ef1abea0b5..61fb81e79f 100644 --- a/docs/source/configuration/csrf.mdx +++ b/docs/source/routing/security/csrf.mdx @@ -5,15 +5,9 @@ description: Prevent cross-site request forgery (CSRF) attacks in the Apollo Gra minVersion: 0.9.0 --- - - ## About CSRF -[Cross-site request forgery (CSRF)](https://owasp.org/www-community/attacks/csrf) attacks use side effects of ["simple"](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests) requests to execute GraphQL operations from requests sent by sites that shouldn't be allowed to communicate with your server, based on the [CORS policy](./cors/) of your GraphOS Router or Apollo Router Core. +[Cross-site request forgery (CSRF)](https://owasp.org/www-community/attacks/csrf) attacks use side effects of ["simple"](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests) requests to execute GraphQL operations from requests sent by sites that shouldn't be allowed to communicate with your server, based on the [CORS policy](/router/configuration/cors/) of your GraphOS Router or Apollo Router Core. Your router's CORS policy enables you to control which websites can talk to your server. In most cases, the browser checks your server's CORS policy by sending a [preflight request](https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request) before sending the actual operation. This is a separate HTTP request. Unlike most HTTP requests (which use the `GET` or `POST` method), this request uses a method called `OPTIONS`. The browser sends an `Origin` header, along with some other headers that start with `Access-Control-`. These headers describe the kind of request that the potentially untrusted JavaScript wants to make. Your server returns a response with `Access-Control-*` headers describing its policies (as described above), and the browser uses that response to decide whether it's OK to send the real request. Processing the `OPTIONS` preflight request never actually executes GraphQL operations. diff --git a/docs/source/executing-operations/demand-control.mdx b/docs/source/routing/security/demand-control.mdx similarity index 97% rename from docs/source/executing-operations/demand-control.mdx rename to docs/source/routing/security/demand-control.mdx index abc7983256..d4ef25212d 100644 --- a/docs/source/executing-operations/demand-control.mdx +++ b/docs/source/routing/security/demand-control.mdx @@ -5,12 +5,6 @@ description: Protect your graph from malicious or demanding clients with Apollo minVersion: 1.48.0 --- - - ## What is demand control? @@ -243,7 +237,7 @@ When enabling `demand_control` for the first time, set it to `measure` mode. Thi -New to router telemetry? See [Router Telemetry](../configuration/telemetry/overview). +New to router telemetry? See [Router Telemetry](/router/configuration/telemetry/overview). @@ -270,7 +264,7 @@ Attributes for `cost` can be applied to instruments, spans, and eventsโ€”anywher | `cost.actual` | boolean | The actual cost of an operation, measured after execution. | | `cost.estimated` | boolean | The estimated cost of an operation before execution. | | `cost.delta` | boolean | The difference between the actual and estimated cost. | -| `cost.result` | boolean | The return code of the cost calculation. `COST_OK` or an [error code](../errors/#demand-control) | +| `cost.result` | boolean | The return code of the cost calculation. `COST_OK` or an [error code](/router/errors/#demand-control) | ### Selectors @@ -428,7 +422,7 @@ An example chart of a histogram: @@ -436,6 +430,6 @@ You can also chart the percentage of operations that would be allowed or rejecte diff --git a/docs/source/routing/security/index.mdx b/docs/source/routing/security/index.mdx new file mode 100644 index 0000000000..e69edf4ff5 --- /dev/null +++ b/docs/source/routing/security/index.mdx @@ -0,0 +1,21 @@ +--- +title: Supergraph Security with GraphOS Router +subtitle: Protect your supergraph at its entry point, the router +--- + +As the public endpoint of a federated GraphQL API, a GraphOS Router has the responsibility for protecting its downstream subgraphs from malicious clients and their requests. + +Its security features contribute to a defense-in-depth approach, where different authentication and authorization measures are applied in various places, from clients to the router itself to subgraphs. The supergraph can also be secured by having the router accept GraphQL operations from validated safelists of operations. + +The features covered in this section include: + +- [**Authorization**](/graphos/routing/security/authorization) - define authorized access to GraphQL fields and types by annotating schemas with authorization primitives +- [**Persisted Queries**](/graphos/routing/security/persisted-queries) - configure the router to allow clients to register and persist cached lists of safe GraphQL queries and operations +- [**Best Practices**](/graphos/platform/security/overview) - best practices for securing supergraphs +- [**CORS**](/graphos/routing/security/cors) - control router access from browser-based clients +- [**CSRF Prevention**](/graphos/routing/security/csrf) - configure cross-site request forgery (CSRF) prevention in the router +- [**Request Limits**](/graphos/routing/security/request-limits) - protect your router from requests exceeding network, parser, and operation-based limits +- [**Demand Control**](/graphos/routing/security/demand-control) - protect your graph from high-cost GraphQL operations +- [**JWT Authentication**](/graphos/routing/security/jwt) - restrict access to credentialed users and systems with JSON Web Tokens (JWT) +- [**Router Authentication**](/graphos/routing/security/router-authentication) - authorization and authentication strategies to secure your graph +- [**Subgraph Authentication**](/graphos/routing/security/subgraph-authentication) - implement subgraph authentication by using AWS SigV4 \ No newline at end of file diff --git a/docs/source/configuration/authn-jwt.mdx b/docs/source/routing/security/jwt.mdx similarity index 88% rename from docs/source/configuration/authn-jwt.mdx rename to docs/source/routing/security/jwt.mdx index bb16070e10..4083721245 100644 --- a/docs/source/configuration/authn-jwt.mdx +++ b/docs/source/routing/security/jwt.mdx @@ -4,17 +4,11 @@ subtitle: Restrict access to credentialed users and systems description: Protect sensitive data by enabling JWT authentication in the Apollo GraphOS Router. Restrict access to credentialed users and systems. --- - - Authentication is crucial to prevent illegitimate access and protect sensitive data in your graph. The GraphOS Router supports request authentication and key rotation via the [JSON Web Token](https://www.rfc-editor.org/rfc/rfc7519) (**JWT**) and [JSON Web Key](https://www.rfc-editor.org/rfc/rfc7517) (**JWK**) standards. This support is compatible with popular identity providers (**IdPs**) like Okta and Auth0. -By enabling JWT authentication, you can block malicious traffic at the _edge_ of your graph instead of relying on [header forwarding](./header-propagation/) to propagate tokens to your subgraphs. +By enabling JWT authentication, you can block malicious traffic at the _edge_ of your graph instead of relying on [header forwarding](/graphos/routing/header-propagation/) to propagate tokens to your subgraphs. @@ -35,7 +29,7 @@ These are the high-level steps of JWT-based authentication with the GraphOS Rout - Your router obtains all of its known JWKs from URLs that you specify in its configuration file. Each URL provides its keys within a single JSON object called a [JWK Set](https://www.rfc-editor.org/rfc/rfc7517#section-5) (or a **JWKS**). - **If validation fails, the router rejects the request.** This can occur if the JWT is malformed, or if it's been expired for more than 60 seconds (this window accounts for synchronization issues). -5. The router extracts all **claims** from the validated JWT and includes them in the request's context, making them available to your [router customizations](../customizations/overview/), such as Rhai scripts. +5. The router extracts all **claims** from the validated JWT and includes them in the request's context, making them available to your [router customizations](/router/customizations/overview/), such as Rhai scripts. 6. Your customizations can handle the request differently depending on the details of the extracted claims, and/or you can propagate the claims to subgraphs to enable more granular access control. - For examples, [see below](#working-with-jwt-claims). @@ -45,7 +39,7 @@ If you use your own custom IdP, [advanced configuration is required](#creating-y Otherwise, if you issue JWTs via a popular third-party IdP (Auth0, Okta, PingOne, etc.), enabling JWT authentication in your router is a two step process described below. -1. Set configuration options for JWT authentication in your router's [YAML config file](./overview/#yaml-config-file), under the `authentication` key: +1. Set configuration options for JWT authentication in your router's [YAML config file](/router/configuration/overview/#yaml-config-file), under the `authentication` key: ```yaml title="router.yaml" authentication: @@ -221,17 +215,17 @@ authorization: **Claims** are the individual details of a JWT's scope. They might include details like the ID of the associated user, any roles assigned to that user, and the JWT's expiration time. [See the spec.](https://www.rfc-editor.org/rfc/rfc7519#section-4) -Because claims are added to the context, you can define custom logic for handling each request based on the details of its claims. You can define this logic within a Rhai script or external coprocessor at the supergraph service level (for more on these options, see [Router Customizations](../customizations/overview/)). +Because claims are added to the context, you can define custom logic for handling each request based on the details of its claims. You can define this logic within a Rhai script or external coprocessor at the supergraph service level (for more on these options, see [Router Customizations](/router/customizations/overview/)). -Below are 2 example [Rhai script](../customizations/rhai/) customizations that demonstrate actions the router can perform based on a request's claims. +Below are 2 example [Rhai script](/graphos/routing/customization/rhai/) customizations that demonstrate actions the router can perform based on a request's claims. ### Example: Forwarding claims to subgraphs as headers -Below is an example [Rhai script](../customizations/rhai/) that forwards a JWT's claims to individual subgraphs via HTTP headers (one header for each claim). This enables each subgraph to define logic to handle (or potentially reject) incoming requests based on claim details. This function should be imported and run in your [`main.rhai`](#example-mainrhai) file. +Below is an example [Rhai script](/graphos/routing/customization/rhai/) that forwards a JWT's claims to individual subgraphs via HTTP headers (one header for each claim). This enables each subgraph to define logic to handle (or potentially reject) incoming requests based on claim details. This function should be imported and run in your [`main.rhai`](#example-mainrhai) file. -This script should be run in the router's `SubgraphService`, which executes before the router sends a subquery to an individual subgraph. [Learn more about router services.](../customizations/rhai#router-request-lifecycle) +This script should be run in the router's `SubgraphService`, which executes before the router sends a subquery to an individual subgraph. [Learn more about router services.](/graphos/routing/customization/rhai#router-request-lifecycle) @@ -260,17 +254,17 @@ fn process_request(request) { -Explicitly listing claims and _always_ setting headers for them is strongly recommended to avoid possible security issues when [forwarding headers](./header-propagation/) to subgraphs. +Explicitly listing claims and _always_ setting headers for them is strongly recommended to avoid possible security issues when [forwarding headers](/graphos/routing/header-propagation/) to subgraphs. ### Example: Forwarding claims to subgraphs as GraphQL extensions -Below is an example [Rhai script](../customizations/rhai/) that forwards a JWT's claims to individual subgraphs via GraphQL extension. This enables each subgraph to define logic to handle (or potentially reject) incoming requests based on claim details. This function should be imported and run in your [`main.rhai`](#example-mainrhai) file. +Below is an example [Rhai script](/graphos/routing/customization/rhai/) that forwards a JWT's claims to individual subgraphs via GraphQL extension. This enables each subgraph to define logic to handle (or potentially reject) incoming requests based on claim details. This function should be imported and run in your [`main.rhai`](#example-mainrhai) file. -This script should be run in the router's `SubgraphService`, which executes before the router sends a subquery to an individual subgraph. [Learn more about router services.](../customizations/rhai#router-request-lifecycle) +This script should be run in the router's `SubgraphService`, which executes before the router sends a subquery to an individual subgraph. [Learn more about router services.](/graphos/routing/customization/rhai#router-request-lifecycle) @@ -292,11 +286,11 @@ fn process_request(request) { ### Example: Throwing errors for invalid claims -Below is an example [Rhai script](../customizations/rhai/) that throws distinct errors for different invalid JWT claim details. This function should be imported and run in your [`main.rhai`](#example-mainrhai) file. +Below is an example [Rhai script](/graphos/routing/customization/rhai/) that throws distinct errors for different invalid JWT claim details. This function should be imported and run in your [`main.rhai`](#example-mainrhai) file. -This script should be run in the router's `SupergraphService`, which executes before the router begins generating the query plan for an operation. [Learn more about router services.](../customizations/rhai#router-request-lifecycle) +This script should be run in the router's `SupergraphService`, which executes before the router begins generating the query plan for an operation. [Learn more about router services.](/graphos/routing/customization/rhai#router-request-lifecycle) @@ -321,7 +315,7 @@ fn process_request(request) { ### Example `main.rhai` -In order to use the above Rhai examples, you must import them into your [`main.rhai`](../customizations/rhai#the-main-file) like this: +In order to use the above Rhai examples, you must import them into your [`main.rhai`](/graphos/routing/customization/rhai#the-main-file) like this: @@ -350,18 +344,18 @@ fn subgraph_service(service, subgraph) { ### Claim augmentation via coprocessors -You may require information beyond what your JSON web tokens provide. For example, a token's claims may include user IDs, which you then use to look up user roles. For situations like this, you can augment the claims from your JSON web tokens with [coprocessors](../customizations/coprocessor#how-it-works). +You may require information beyond what your JSON web tokens provide. For example, a token's claims may include user IDs, which you then use to look up user roles. For situations like this, you can augment the claims from your JSON web tokens with [coprocessors](/router/customizations/coprocessor#how-it-works). -A [`RouterService` coprocessor](../customizations/coprocessor#how-it-works) is appropriate for augmenting claims since the router calls it directly after receiving a client request. The router calls it after the JWT authentication plugin, so you can use a `RouterService` coprocessor to: +A [`RouterService` coprocessor](/router/customizations/coprocessor#how-it-works) is appropriate for augmenting claims since the router calls it directly after receiving a client request. The router calls it after the JWT authentication plugin, so you can use a `RouterService` coprocessor to: - receive the list of claims extracted from the JWT - use information like the `sub` (subject) claim to look up the user in an external database or service - insert additional data in the claims list - return the claims list to the router -For example, if you use this [router configuration](./overview#yaml-config-file): +For example, if you use this [router configuration](/router/configuration/overview#yaml-config-file): ```yaml title="router.yaml" authentication: @@ -417,7 +411,7 @@ The coprocessor can then look up the user with the identifier specified in the ` } ``` -For more information, refer to [the coprocessor documentation](../customizations/coprocessor/). +For more information, refer to [the coprocessor documentation](/router/customizations/coprocessor/). @@ -745,13 +739,13 @@ This matching strategy is necessary because some identity providers (IdPs) don't Because the GraphOS Router handles validating incoming JWTs, you rarely need to pass those JWTs to individual subgraphs in their entirety. Instead, you usually want to [pass JWT _claims_ to subgraphs](#example-forwarding-claims-to-subgraphs-as-headers) to enable fine-grained access control. -If you _do_ need to pass entire JWTs to subgraphs, you can do so via the GraphOS Router's general-purpose [HTTP header propagation settings](./header-propagation). +If you _do_ need to pass entire JWTs to subgraphs, you can do so via the GraphOS Router's general-purpose [HTTP header propagation settings](/graphos/routing/header-propagation). ## Observability -If your router enables [tracing](./telemetry/exporters/tracing/overview), the JWT authentication plugin has its own tracing span: `authentication_plugin` +If your router enables [tracing](/router/configuration/telemetry/exporters/tracing/overview), the JWT authentication plugin has its own tracing span: `authentication_plugin` -If your router enables [metrics collection via Prometheus](./telemetry/exporters/metrics/prometheus), the JWT authentication plugin provides and exports the following metrics: +If your router enables [metrics collection via Prometheus](/router/configuration/telemetry/exporters/metrics/prometheus), the JWT authentication plugin provides and exports the following metrics: - `apollo_authentication_failure_count` - `apollo_authentication_success_count` diff --git a/docs/source/configuration/persisted-queries.mdx b/docs/source/routing/security/persisted-queries.mdx similarity index 69% rename from docs/source/configuration/persisted-queries.mdx rename to docs/source/routing/security/persisted-queries.mdx index 0caabc7d1d..5befd7071c 100644 --- a/docs/source/configuration/persisted-queries.mdx +++ b/docs/source/routing/security/persisted-queries.mdx @@ -5,19 +5,13 @@ description: Secure your federated GraphQL API by creating an allowlist of trust minVersion: 1.25.0 --- - - ## Differences from automatic persisted queries -The Apollo Router Core also supports a related feature called [automatic persisted queries](./in-memory-caching#caching-automatic-persisted-queries-apq) (APQ). With APQ, clients can execute a GraphQL operation by sending the SHA256 hash of its operation string instead of the entire string. **APQ doesn't support safelisting** because the router updates its APQ cache over time with _any_ operations it receives. +The Apollo Router Core also supports a related feature called [automatic persisted queries](/router/configuration/in-memory-caching#caching-automatic-persisted-queries-apq) (APQ). With APQ, clients can execute a GraphQL operation by sending the SHA256 hash of its operation string instead of the entire string. **APQ doesn't support safelisting** because the router updates its APQ cache over time with _any_ operations it receives. For more details on differences between APQ and this feature, see the [GraphOS persisted queries documentation](/graphos/operations/persisted-queries#differences-from-automatic-persisted-queries). @@ -76,7 +70,7 @@ If used with the [`safelist`](#safelist) option, the router logs unregistered an -By default, the router [prewarms the query plan cache](./in-memory-caching#cache-warm-up) using all operations on the PQL when a new schema is loaded, but not at startup. Using the `experimental_prewarm_query_plan_cache` option, you can tell the router to prewarm the cache using the PQL on startup as well, or tell it not to prewarm the cache when reloading the schema. (This does not affect whether the router prewarms the query plan cache with recently-used operations from its in-memory cache.) Prewarming the cache means can reduce request latency by ensuring that operations are pre-planned when requests are received, but can make startup or schema reloads slower. +By default, the router [prewarms the query plan cache](/router/configuration/in-memory-caching#cache-warm-up) using all operations on the PQL when a new schema is loaded, but not at startup. Using the `experimental_prewarm_query_plan_cache` option, you can tell the router to prewarm the cache using the PQL on startup as well, or tell it not to prewarm the cache when reloading the schema. (This does not affect whether the router prewarms the query plan cache with recently-used operations from its in-memory cache.) Prewarming the cache means can reduce request latency by ensuring that operations are pre-planned when requests are received, but can make startup or schema reloads slower. ```yaml title="router.yaml" persisted_queries: @@ -116,7 +110,7 @@ apq: -To enable safelisting, you _must_ turn off [automatic persisted queries](./in-memory-caching#caching-automatic-persisted-queries-apq) (APQs). APQs let clients [register arbitrary operations at runtime](/graphos/operations/persisted-queries/#differences-from-automatic-persisted-queries) while safelisting restricts operations to those that have been explicitly registered. +To enable safelisting, you _must_ turn off [automatic persisted queries](/router/configuration/in-memory-caching#caching-automatic-persisted-queries-apq) (APQs). APQs let clients [register arbitrary operations at runtime](/graphos/operations/persisted-queries/#differences-from-automatic-persisted-queries) while safelisting restricts operations to those that have been explicitly registered. @@ -140,10 +134,10 @@ apq: -To enable safelisting, you _must_ turn off [automatic persisted queries](./in-memory-caching#caching-automatic-persisted-queries-apq) (APQs). APQs let clients [register arbitrary operations at runtime](/graphos/operations/persisted-queries/#differences-from-automatic-persisted-queries) while safelisting restricts operations to those that have been explicitly registered. +To enable safelisting, you _must_ turn off [automatic persisted queries](/router/configuration/in-memory-caching#caching-automatic-persisted-queries-apq) (APQs). APQs let clients [register arbitrary operations at runtime](/graphos/operations/persisted-queries/#differences-from-automatic-persisted-queries) while safelisting restricts operations to those that have been explicitly registered. ## Limitations -* **Unsupported with offline license**. An GraphOS Router using an [offline Enterprise license](../enterprise-features/#offline-enterprise-license) cannot use safelisting with persisted queries. The feature relies on Apollo Uplink to fetch persisted query manifests, so it doesn't work as designed when the router is disconnected from Uplink. +* **Unsupported with offline license**. An GraphOS Router using an [offline Enterprise license](/router/enterprise-features/#offline-enterprise-license) cannot use safelisting with persisted queries. The feature relies on Apollo Uplink to fetch persisted query manifests, so it doesn't work as designed when the router is disconnected from Uplink. diff --git a/docs/source/configuration/operation-limits.mdx b/docs/source/routing/security/request-limits.mdx similarity index 60% rename from docs/source/configuration/operation-limits.mdx rename to docs/source/routing/security/request-limits.mdx index 2f24ce620b..3cbe0ff552 100644 --- a/docs/source/configuration/operation-limits.mdx +++ b/docs/source/routing/security/request-limits.mdx @@ -1,24 +1,43 @@ --- -title: Enforcing Operation Limits in the GraphOS Router -subtitle: Set constraints on depth, height, aliases, and root fields -description: Ensure your GraphQL operations are secure with GraphOS Router's operation limits. Set constraints on depth, height, aliases, and root fields. +title: Request Limits +subtitle: Protect your router from requests exceeding network, parser, and operation-based limits +redirectFrom: + - /router/configuration/operation-limits/ --- - +For enhanced security, the GraphOS Router can reject requests that violate any of the following kinds of limits: + +- Operation-based semantic limits +- Network-based limits +- Parser-based lexical limits + +```yaml title="router.yaml" +limits: + # Network-based limits + http_max_request_bytes: 2000000 # Default value: 2 MB + + # Parser-based limits + parser_max_tokens: 15000 # Default value + parser_max_recursion: 500 # Default value + + # Operation-based limits (Enterprise only) + max_depth: 100 + max_height: 200 + max_aliases: 30 + max_root_fields: 20 +``` + +## Operation-based limits You can define **operation limits** in your router's configuration to reject potentially malicious requests. An operation that exceeds _any_ specified limit is rejected (unless you run your router in [`warn_only` mode](#warn_only-mode)). -## Setup +### Setup -To use operation limits, you must run v1.17 or later of the GraphOS Router. [Download the latest version.](../quickstart#download-options) +To use operation limits, you must run v1.17 or later of the Apollo Router. [Download the latest version.](/graphos/reference/router/self-hosted-install/#download-options) -You define operation limits in your router's [YAML config file](./overview/#yaml-config-file), like so: +You define operation limits in your router's [YAML config file](/graphos/reference/router/configuration#yaml-config-file), like so: ```yaml title="router.yaml" limits: @@ -33,9 +52,9 @@ limits: Each limit takes an integer value. You can define any combination of [supported limits](#supported-limits). -## Supported limits +### Supported limits -### `max_depth` +#### `max_depth` Limits the deepest nesting of selection sets in an operation, including fields in fragments. @@ -57,7 +76,7 @@ fragment bookDetails on Book { } ``` -### `max_height` +#### `max_height` Limits the number of unique fields included in an operation, including fields of fragments. If a particular field is included _multiple_ times via aliases, it's counted only _once_. @@ -75,7 +94,7 @@ query GetUser { Each unique field increments an operation's height by one, regardless of that field's return type (scalar, object, or list). -### `max_aliases` +#### `max_aliases` Limits the total number of aliased fields in an operation, including fields of fragments. @@ -93,7 +112,7 @@ query GetUser { Each aliased field increments the alias count by one, regardless of that field's return type (scalar, object, or list). -### `max_root_fields` +#### `max_root_fields` Limits the number of root fields in an operation, including root fields in fragments. If a particular root field is included _multiple_ times via aliases, _each usage_ is counted. @@ -113,7 +132,7 @@ query GetTopProducts { } ``` -## `warn_only` mode +### `warn_only` mode If you run your router in `warn_only` mode, operations that exceed defined limits are _not_ rejected. Instead, the router processes these operations as usual and emits a `WARN` trace that notes all exceeded limits, like so: @@ -123,14 +142,14 @@ If you run your router in `warn_only` mode, operations that exceed defined limit Running in `warn_only` mode can be useful while you're testing to determine the most appropriate limits to set for your supergraph. -You can enable or disable `warn_only` mode in your router's [YAML config file](./overview/#yaml-config-file), like so: +You can enable or disable `warn_only` mode in your router's [YAML config file](/graphos/reference/router/configuration#yaml-config-file), like so: ```yaml title="router.yaml" limits: warn_only: true # warn_only mode always enabled ``` -## Response format for exceeded limits +### Response format for exceeded limits Whenever your router rejects a request because it exceeds an operation limit, the router responds with a 400 HTTP status code and a standard GraphQL error response body: @@ -151,13 +170,13 @@ Whenever your router rejects a request because it exceeds an operation limit, th If you run your router in [`warn_only` mode](#warn_only-mode), the router logs the limit violation but executes the operation as normal, returning a 200 status code with the expected response. -## Using telemetry to set operation limits +### Using telemetry to set operation-based limits Router telemetry can help you set operation limits, especially when you have a large number of existing operations. You can measure incoming operations over a fixed duration, then use the captured data as a baseline configuration. -### Logging values +#### Logging values -To log limit information about every operation, you can configure the router with a [custom event](/router/configuration/telemetry/instrumentation/events#custom-events) to log the values of aliases, depth, height, and root_fields for each operation: +To log limit information about every operation, you can configure the router with a [custom event](/graphos/reference/router/telemetry/instrumentation/events#custom-events) to log the values of aliases, depth, height, and root_fields for each operation: ```yaml title="router.yaml" telemetry: @@ -186,9 +205,9 @@ For a large amount of traffic, you may prefer to collect and export metrics to y -### Collecting metrics +#### Collecting metrics -To capture and view metrics to help set your operation limits, you can configure the router to collect [custom metrics](/router/configuration/telemetry/instrumentation/instruments#custom-instruments) on the values of aliases, depth, height, and root_fields for each operation: +To capture and view metrics to help set your operation limits, you can configure the router to collect [custom metrics](/graphos/reference/router/telemetry/instrumentation/instruments#custom-instruments) on the values of aliases, depth, height, and root_fields for each operation: ```yaml title="router.yaml" telemetry: @@ -237,5 +256,60 @@ telemetry: unit: number description: "Root fields for an operation" ``` +You should also configure the router to [export metrics](/graphos/reference/router/telemetry/metrics-exporters/overview) to your APM tool. + +## Network-based limits + +### `http_max_request_bytes` + +Limits the amount of data read from the network for the body of HTTP requests, +to protect against unbounded memory consumption. +This limit is checked before JSON parsing. +Both the GraphQL document and associated variables count toward it. + +The default value is `2000000` bytes, 2 MB. + +Before increasing this limit significantly consider testing performance +in an environment similar to your production, especially if some clients are untrusted. +Many concurrent large requests could cause the router to run out of memory. + +## Parser-based limits + +### `parser_max_tokens` + +Limits the number of tokens a query document can include. This counts _all_ tokens, including both [lexical and ignored tokens](https://spec.graphql.org/October2021/#sec-Language.Source-Text.Lexical-Tokens). -You should also configure the router to [export metrics](/router/configuration/telemetry/exporters/metrics/overview) to your APM tool. +The default value is `15000`. + +### `parser_max_recursion` + +Limits the deepest level of recursion allowed by the router's GraphQL parser to prevent stack overflows. This corresponds to the deepest nesting level of any single GraphQL operation or fragment defined in a query document. + +The default value is `500`. + +In the example below, the `GetProducts` operation has a recursion of three, and the `ProductVariation` fragment has a recursion of two. Therefore, the _max_ recursion of the query document is three. + +```graphql +query GetProducts { + allProducts { #1 + ...productVariation + delivery { #2 + fastestDelivery #3 + } + } +} + +fragment ProductVariation on Product { + variation { #1 + name #2 + } +} +``` + +Note that the router calculates the recursion depth for each operation and fragment _separately_. Even if a fragment is included in an operation, that fragment's recursion depth does not contribute to the _operation's_ recursion depth. + + + +In versions of the Apollo Router prior to 1.17, this limit was defined via the config option `experimental_parser_recursion_limit`. + + diff --git a/docs/source/routing/security/router-authentication.mdx b/docs/source/routing/security/router-authentication.mdx new file mode 100644 index 0000000000..cdcc22ef4e --- /dev/null +++ b/docs/source/routing/security/router-authentication.mdx @@ -0,0 +1,214 @@ +--- +title: Authenticating Requests with the GraphOS Router +subtitle: Use authorization and authentication strategies to secure your graph +description: Combine authorization and authentication strategies with the GraphOS Router to secure your graph through defense in depth. +published: 2022-06-13 +id: TN0004 +tags: [server, router, auth] +redirectFrom: + - /technotes/TN0004-router-authentication/ +--- + + + +Self-hosting the GraphOS Router is limited to [GraphOS Enterprise plans](https://www.apollographql.com/pricing). Other plan types use [managed cloud routing with GraphOS](/graphos/cloud-routing). Check out the [pricing page](https://www.apollographql.com/pricing#graphos-router) to learn more. + + + + + +If you're an enterprise customer looking for more material on this topic, try the [Enterprise best practices: Router extensibility](https://www.apollographql.com/tutorials/router-extensibility) course on Odyssey. + +Not an enterprise customer? [Learn about GraphOS for Enterprise.](https://www.apollographql.com/pricing) + + + +When using the router as the entry point to your federated supergraph, you have a few options for authenticating incoming client requests: + +- [Use authorization directives](#use-authorization-directives) +- [Delegate authentication to your subgraphs.](#authenticate-in-subgraphs) +- [Use the JWT authentication plugin](#use-the-jwt-authentication-plugin) to your supergraph. +- [Use a coprocessor](#use-a-coprocessor). + +In fact, we recommend you [combine all three strategies](#combining-authentication-strategies) to create a more robust authentication system! + +## Use authorization directives + +In addition to the approaches outlined below, you can use [authorization directives](/graphos/routing/security/authorization/) to enforce authorization at the router layer. +This allows you to authorize requests prior to them hitting your subgraphs saving on bandwidth and processing time. + + + +This is an [Enterprise feature](/router/enterprise-features) of the GraphOS Router. +It requires an organization with a [GraphOS Enterprise plan](https://www.apollographql.com/pricing/). + + + +```mermaid +sequenceDiagram + Client->>Router: Request with token + note over Router: Validate request + alt Request is invalid + Router->>Client: Respond 401 Unauthorized + else Request is valid + Router->>Subgraph: Request Data + end +``` + +Once the request's claims are made available via the JWT validation or a coprocessor, they can be used to match against the required type and field scopes to enforce authorization policies. + +```graphql +# Request's authorization claims must contain `read:users` +type Query { + users: [User!]! @requiresScopes(scopes: [["read:users"]]) +} + +# Request must be authenticated +type Mutation { + updateUser(input: UpdateUserInput!): User! @authenticated +} +``` + +Pros: + +- Validating authorization before processing requests enables the early termination of unauthorized requests reducing the load on your services +- Declarative approach that can be adopted and maintained by each subgraph while enforced centrally + +Cons + +- Schema updates will need to be made to each subgraph to opt into this authorization model + +## Authenticate in subgraphs + +The simplest authentication strategy is to delegate authentication to your individual subgraph services. + +```mermaid +sequenceDiagram + Client->>Router: Request with token + Router->>Subgraph: Request with token + note over Subgraph: Authenticate request with token +``` + +To pass `Authentication` headers from client requests to your subgraphs, add the following to your router's YAML configuration file: + +```yaml +headers: + all: + request: + - propagate: + named: authorization +``` + +#### Pros + +- Requires minimal changes to your router configuration. +- Can take advantage of existing authentication code in subgraphs, which is often tied to authorization logic for data sources. + +#### Cons + +- Each subgraph that contributes to resolving a request needs to authenticate that request. +- If subgraphs are written in different languages, maintaining consistent authentication code for each is complex. + +## Use the JWT Authentication plugin + +As of router v1.13, you can use the [JWT Authentication plugin](/router/configuration/authn-jwt) to validate JWT-based authentication tokens in your supergraph. + + + +```mermaid +sequenceDiagram + Client->>Router: Request with JWT + Router->>JWKS Endpoint: Fetch key set + JWKS Endpoint->>Router: Public keys + note over Router: Validate JWT + note over Router: Extract claims in Rhai + Router->>Subgraph: Request with extracted claims in headers + note over Subgraph: Check claims on headers +``` + +```yaml +authentication: + jwt: + jwks: + - url: https://dev-zzp5enui.us.auth0.com/.well-known/jwks.json +``` + +Pros: + +- The router prevents unauthenticated requests from reaching your subgraphs. +- The router can extract claims from the JWT and pass them to your subgraphs as headers, reducing logic needed in your subgraphs. + +Cons: + +- It supports only JWT-based authentication with keys from a JWKS endpoint. + +## Use a coprocessor + +If you have a custom authentication strategy, you can use a [coprocessor](/graphos/routing/customization/coprocessor) to implement it. + + + +```mermaid +sequenceDiagram + Client->>Router: Request with token + Router->>Coprocessor: Request with headers and context + note over Coprocessor: Validate request + alt Request is invalid + Coprocessor->>Router: Respond { control: { break: 401 } } + else Request is valid + Coprocessor->>Router: Respond { control: "continue" } + note over Coprocessor: Can also add new headers + end + Router->>Subgraph: Request with new headers + note over Subgraph: Check claims on headers +``` + +```yaml +coprocessor: + url: http://127.0.0.1:8081 + router: + request: + headers: true +``` + +This example coprocessor is written in Node.js and uses Express: + +```js +const app = express(); +app.use(bodyParser.json()); +app.post('/', async (req, res) => { + const {headers} = req.body; + const token = headers.authorization; + const isValid = await validateToken(token); + if (!isValid) { + res.json({ + ...req.body, + control: {break: 401} + }); + } else { + res.json({ + ...req.body, + control: 'continue', + headers: {'x-claims': extractClaims(token)} + }); + } +}); +``` + +Pros: + +- You can implement any authentication strategy in any language or framework, as long as the coprocessor provides an HTTP endpoint. +- You can use the coprocessor to add headers to requests, which can be used by your subgraphs for additional authorization. + +Cons: + +- The initial lift of implementing a coprocessor is non-trivial, but once it's in place you can leverage it for any number of router customizations. + +## Combining authentication strategies + +You can combine the strategies to handle a number of authentication requirements and practice "defense-in-depth": + +1. Use the JWT Authentication plugin to validate JWT-based authentication tokens. +2. Use auth directives to enforce authentication and authorization and at the supergraph layer +3. Use a coprocessor to identify traffic using a legacy authentication strategy and convert legacy session tokens to JWTs. +4. Forward JWTs to subgraphs for additional authorization. diff --git a/docs/source/configuration/authn-subgraph.mdx b/docs/source/routing/security/subgraph-authentication.mdx similarity index 94% rename from docs/source/configuration/authn-subgraph.mdx rename to docs/source/routing/security/subgraph-authentication.mdx index 3d06ef578f..d138e981d7 100644 --- a/docs/source/configuration/authn-subgraph.mdx +++ b/docs/source/routing/security/subgraph-authentication.mdx @@ -5,12 +5,6 @@ description: Secure communication to AWS subgraphs via the Apollo GraphOS Router minVersion: 1.27.0 --- - - The GraphOS Router and Apollo Router Core support subgraph request authentication and key rotation via [AWS Signature Version 4](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html) (SigV4). This allows you to secure communication to AWS subgraphs by making sure a subgraph request was made by the router, and the payload hasn't been tampered with. diff --git a/docs/source/routing/security/tls.mdx b/docs/source/routing/security/tls.mdx new file mode 100644 index 0000000000..97d1af2187 --- /dev/null +++ b/docs/source/routing/security/tls.mdx @@ -0,0 +1,135 @@ +--- +title: TLS +subtitle: Secure client-side and subgraph-side communications +redirectFrom: + - /router/configuration/overview/#tls +--- + +The GraphOS Router supports TLS to authenticate and encrypt communications, both on the client side and the subgraph side. It works automatically on the subgraph side if the subgraph URL starts with `https://`. + +## Configuring TLS + +TLS support is configured in the `tls` section, under the `supergraph` key for the client side, and the `subgraph` key for the subgraph side, with configuration possible for all subgraphs and overriding per subgraph. + +The list of supported TLS versions and algorithms is static, it cannot be configured. + +Supported TLS versions: +* TLS 1.2 +* TLS 1.3 + +Supported cipher suites: +* TLS13_AES_256_GCM_SHA384 +* TLS13_AES_128_GCM_SHA256 +* TLS13_CHACHA20_POLY1305_SHA256 +* TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 +* TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 +* TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 +* TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 +* TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 +* TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + +Supported key exchange groups: +* X25519 +* SECP256R1 +* SECP384R1 + +## TLS termination + +Clients can connect to the router directly over HTTPS, without terminating TLS in an intermediary. You can configure this in the `tls` configuration section: + +```yaml +tls: + supergraph: + certificate: ${file./path/to/certificate.pem} + certificate_chain: ${file./path/to/certificate_chain.pem} + key: ${file./path/to/key.pem} +``` + +To set the file paths in your configuration with Unix-style expansion, you can follow the examples in the [variable expansion](#variable-expansion) guide. + +The router expects the file referenced in the `certificate_chain` value to be a combination of several PEM certificates concatenated together into a single file (as is commonplace with Apache TLS configuration). + +## Overriding certificate authorities for subgraphs + +The router verifies TLS connections to subgraphs using the list of certificate authorities the system provides. You can override this list with a combination of global and per-subgraph settings: + +```yaml +tls: + subgraph: + # Use these certificate authorities unless overridden per-subgraph + all: + certificate_authorities: "${file./path/to/ca.crt}" + # Override global setting for individual subgraphs + subgraphs: + products: + certificate_authorities: "${file./path/to/product_ca.crt}" +``` + +The router expects the file referenced in the `certificate_chain` value to be a combination of several PEM certificates concatenated together into a single file (as is commonplace with Apache TLS configuration). + +You can only configure these certificates via the router's configuration since using `SSL_CERT_FILE` also overrides certificates for sending telemetry and communicating with Apollo Uplink. + +If the subgraph is presenting a self-signed certificate, it must be generated with the proper file extension and with `basicConstraints` turned off. You can generate it with the following command line command from a certificate signing request, in this example, `server.csr`: + +``` +openssl x509 -req -in server.csr -signkey server.key -out server.crt -extfile v3.ext +``` + +You can generate a `v3.ext` extension file like so: + +``` +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid:always,issuer:always +# this has to be turned off +# basicConstraints = CA:TRUE +keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyAgreement, keyCertSign +subjectAltName = DNS:local.apollo.dev +issuerAltName = issuer:copy +``` + + + +Make sure to change the `subjectAltName` field to the subgraph's name. + + + +This produces the file as `server.crt` which can be used in `certificate_authorities`. + +## TLS client authentication for subgraph requests + +The router supports mutual TLS authentication (mTLS) with the subgraphs. This means that it can authenticate itself to the subgraph using a certificate chain and a cryptographic key. It can be configured as follows: + +```yaml +tls: + subgraph: + # Use these certificates and key unless overridden per-subgraph + all: + client_authentication: + certificate_chain: ${file./path/to/certificate_chain.pem} + key: ${file./path/to/key.pem} + # Override global setting for individual subgraphs + subgraphs: + products: + client_authentication: + certificate_chain: ${file./path/to/certificate_chain.pem} + key: ${file./path/to/key.pem} +``` + +## Redis TLS configuration + +For Redis TLS connections, you can set up a client certificate or override the root certificate authority by configuring `tls` in your router's [YAML config file](https://www.apollographql.com/docs/router/overview/#yaml-config-file). For example: + +```yaml +apq: + router: + cache: + redis: + urls: [ "rediss://redis.example.com:6379" ] + #highlight-start + tls: + certificate_authorities: ${file./path/to/ca.crt} + client_authentication: + certificate_chain: ${file./path/to/certificate_chain.pem} + key: ${file./path/to/key.pem} + #highlight-end +``` diff --git a/docs/source/containerization/docker.mdx b/docs/source/routing/self-hosted/containerization/docker.mdx similarity index 94% rename from docs/source/containerization/docker.mdx rename to docs/source/routing/self-hosted/containerization/docker.mdx index 11aacdc11a..605b8723c1 100644 --- a/docs/source/containerization/docker.mdx +++ b/docs/source/routing/self-hosted/containerization/docker.mdx @@ -4,7 +4,7 @@ subtitle: Run the router container image in Docker description: Run the Apollo Router Core container image in Docker with examples covering basic setup, configuration overrides, debugging, and building custom Docker images. --- -import ElasticNotice from '../../shared/elastic-notice.mdx'; +import ElasticNotice from '../../../../shared/elastic-notice.mdx'; This guide provides the following examples of running an Apollo Router Core container image in Docker: @@ -22,7 +22,7 @@ The exact image version to use depends on which release you wish to use. In the ## Basic example running router in Docker -To run the router, your Docker container must have the [`APOLLO_GRAPH_REF`](../configuration/overview#apollo_graph_ref) and [`APOLLO_KEY`](../configuration/overview#apollo_key) environment variables set to your graph ref and API key, respectively. +To run the router, your Docker container must have the [`APOLLO_GRAPH_REF`](/router/configuration/overview#apollo_graph_ref) and [`APOLLO_KEY`](/router/configuration/overview#apollo_key) environment variables set to your graph ref and API key, respectively. Here's a basic example of running a router image in Docker. Make sure to replace `` with whichever version you want to use, such as `v1.32.0`. @@ -36,7 +36,7 @@ docker run -p 4000:4000 \ This command downloads your supergraph schema from Apollo and uses a default configuration that listens for connections on port `4000`. -For more complex configurations, such as overriding subgraph URLs or propagating headers, see [Router Configuration](../configuration/overview/). +For more complex configurations, such as overriding subgraph URLs or propagating headers, see [Router Configuration](/router/configuration/overview/). ## Override the configuration @@ -65,7 +65,7 @@ In this example we are mounting a file from the host system (`/home/user/router. ## Passing command-line arguments to the router binary -By default, the `router` command invoked inside the published container doesn't set any of the [available command-line options](../configuration/overview#command-line-options). To set them, append the desired option(s) to the `docker run` command. +By default, the `router` command invoked inside the published container doesn't set any of the [available command-line options](/router/configuration/overview#command-line-options). To set them, append the desired option(s) to the `docker run` command. For example, to start the router using the `--log debug` option, use the following `docker run` command with the option added at the end: diff --git a/docs/source/containerization/overview.mdx b/docs/source/routing/self-hosted/containerization/index.mdx similarity index 90% rename from docs/source/containerization/overview.mdx rename to docs/source/routing/self-hosted/containerization/index.mdx index 44c2302952..0b9a452de0 100644 --- a/docs/source/containerization/overview.mdx +++ b/docs/source/routing/self-hosted/containerization/index.mdx @@ -4,7 +4,7 @@ subtitle: Run router images in containers description: Containerize the Apollo GraphOS Router for portability and scalability. Choose from default or debug images. Deploy in Kubernetes or run in Docker. --- -import ElasticNotice from '../../shared/elastic-notice.mdx'; +import ElasticNotice from '../../../../shared/elastic-notice.mdx'; Apollo provides container images of the Apollo Router Core that you can self-host and run with GraphOS as GraphOS Routers. By containerizing the router, you can run it in a cluster and leverage the portability, scalability, and high availability benefits of containerization. Containers can also simplify and speed up local development. @@ -27,5 +27,5 @@ A router image has the following layout: The default behavior of a router image is suitable for a basic deployment or development scenario. For examples of customizing and deploying router images in specific environments, see the guides for: -* [Deploying in Kubernetes](./kubernetes/). -* [Running in Docker](./docker/) +* [Deploying in Kubernetes](/router/containerization/kubernetes/). +* [Running in Docker](/router/containerization/docker/) diff --git a/docs/source/containerization/kubernetes.mdx b/docs/source/routing/self-hosted/containerization/kubernetes.mdx similarity index 87% rename from docs/source/containerization/kubernetes.mdx rename to docs/source/routing/self-hosted/containerization/kubernetes.mdx index 7ad8ffa50a..344a982aa3 100644 --- a/docs/source/containerization/kubernetes.mdx +++ b/docs/source/routing/self-hosted/containerization/kubernetes.mdx @@ -4,9 +4,9 @@ subtitle: Self-hosted deployment of the router in Kubernetes description: Deploy the Apollo GraphOS Router or Apollo Router Core in Kubernetes using Helm charts. Customize configurations, enable metrics, and choose values for migration. --- -import ElasticNotice from '../../shared/elastic-notice.mdx'; -import HelmShowOutput from '../../shared/helm-show-router-output.mdx'; -import CoprocTypicalConfig from '../../shared/coproc-typical-config.mdx'; +import ElasticNotice from '../../../../shared/elastic-notice.mdx'; +import HelmShowOutput from '../../../../shared/helm-show-router-output.mdx'; +import CoprocTypicalConfig from '../../../../shared/coproc-typical-config.mdx'; Learn how to deploy a self-hosted router (GraphOS Router or Apollo Router Core) in Kubernetes using Helm charts. @@ -46,7 +46,7 @@ The path to the OCI router chart is `oci://ghcr.io/apollographql/helm-charts/rou -You customize a deployed router with the same [command-line options and YAML configuration](../configuration/overview) but under different Helm CLI options and YAML keys. +You customize a deployed router with the same [command-line options and YAML configuration](/router/configuration/overview) but under different Helm CLI options and YAML keys. ## Basic deployment @@ -54,8 +54,8 @@ Follow this guide to deploy the Router using Helm to install the basic chart pr Each router chart has a `values.yaml` file with router and deployment settings. The released, unedited file has a few explicit settings, including: -* Default container ports for the router's [HTTP server](../configuration/overview/#listen-address), [health check endpoint](../configuration/health-checks), and [metrics endpoint](../configuration/telemetry/exporters/metrics/overview). -* A command-line argument to enable [hot reloading of the router](../configuration/overview/#--hr----hot-reload). +* Default container ports for the router's [HTTP server](/router/configuration/overview/#listen-address), [health check endpoint](/router/configuration/health-checks), and [metrics endpoint](/router/configuration/telemetry/exporters/metrics/overview). +* A command-line argument to enable [hot reloading of the router](/router/configuration/overview/#--hr----hot-reload). * A single replica. @@ -104,7 +104,7 @@ To manage the system resources you need to deploy the router on Kubernetes: ### Set up graph -Set up your self-hosted graph and get its [graph ref](../configuration/overview/#apollo_graph_ref) and [API key](../configuration/overview/#apollo_graph_ref). +Set up your self-hosted graph and get its [graph ref](/router/configuration/overview/#apollo_graph_ref) and [API key](/router/configuration/overview/#apollo_graph_ref). If you need a guide to set up your graph, you can follow [the self-hosted router quickstart](/graphos/quickstart/self-hosted) and complete [step 1 (Set up Apollo tools)](/graphos/quickstart/self-hosted/#1-set-up-apollo-tools), [step 4 (Obtain your subgraph schemas)](/graphos/quickstart/self-hosted/#4-obtain-your-subgraph-schemas), and [step 5 (Publish your subgraph schemas)](/graphos/quickstart/self-hosted/#5-publish-your-subgraph-schemas). @@ -117,8 +117,8 @@ helm install --namespace --set managedFederation.apiKey=" ## Deploy with metrics endpoints -The router supports [metrics endpoints for Prometheus and OpenTelemetry protocol (OTLP)](../configuration/telemetry/exporters/metrics/overview). A [basic deployment](#basic-deployment) doesn't enable metrics endpoints, because the router chart disables both Prometheus (explicitly) and OTLP (by omission). +The router supports [metrics endpoints for Prometheus and OpenTelemetry protocol (OTLP)](/router/configuration/telemetry/exporters/metrics/overview). A [basic deployment](#basic-deployment) doesn't enable metrics endpoints, because the router chart disables both Prometheus (explicitly) and OTLP (by omission). To enable metrics endpoints in your deployed router through a YAML configuration file: @@ -176,20 +176,20 @@ To enable metrics endpoints in your deployed router through a YAML configuration ## Deploy with Rhai scripts -The router supports [Rhai scripting](../customizations/rhai) to add custom functionality. +The router supports [Rhai scripting](/graphos/routing/customization/rhai) to add custom functionality. Enabling Rhai scripts in your deployed router requires mounting an extra volume for your Rhai scripts and getting your scripts onto the volume. That can be done by following steps in [a separate example for creating a custom in-house router chart](https://github.com/apollographql/in-house-router-example). The example creates a new (in-house) chart that wraps (and depends on) the released router chart, and the new chart has templates that add the necessary configuration to allow Rhai scripts for a deployed router. ## Deploy with a coprocessor -The router supports [external coprocessing](../customizations/coprocessor) to run custom logic on requests throughout the [router's request-handling lifecycle](../customizations/rhai/#router-request-lifecycle). +The router supports [external coprocessing](/router/customizations/coprocessor) to run custom logic on requests throughout the [router's request-handling lifecycle](/graphos/routing/customization/rhai/#router-request-lifecycle). A deployed coprocessor has its own application image and container in the router pod. To configure a coprocessor and its container for your deployed router through a YAML configuration file: 1. Create a YAML file, `my_values.yaml`, to contain additional values that override default values. -1. Edit `my_values.yaml` to configure a coprocessor for the router. For reference, follow the [typical](../customizations/coprocessor#typical-configuration) and [minimal](../customizations/coprocessor#minimal-configuration) configuration examples, and apply them to `router.configuration.coprocessor`. +1. Edit `my_values.yaml` to configure a coprocessor for the router. For reference, follow the [typical](/router/customizations/coprocessor#typical-configuration) and [minimal](/router/customizations/coprocessor#minimal-configuration) configuration examples, and apply them to `router.configuration.coprocessor`. @@ -239,7 +239,7 @@ This is not specifically a router issue and Istio has instructions on how to man ## Configure for migration from gateway -When [migrating from `@apollo/gateway` to the router](../migrating-from-gateway), consider the following tips to maximize the compatibility of your router deployment. +When [migrating from `@apollo/gateway` to the router](/router/migrating-from-gateway), consider the following tips to maximize the compatibility of your router deployment. ### Increase maximum request bytes diff --git a/docs/source/routing/self-hosted/containerization/optimize-build.mdx b/docs/source/routing/self-hosted/containerization/optimize-build.mdx new file mode 100644 index 0000000000..90e2dc3dd4 --- /dev/null +++ b/docs/source/routing/self-hosted/containerization/optimize-build.mdx @@ -0,0 +1,58 @@ +--- +title: Optimizing Custom GraphOS Router Builds +subtitle: Enhance performance, minimize build time, and address system requirements +description: Recommendations and considerations for minimizing build time when using custom Apollo GraphOS Router builds. +published: 2023-01-19 +id: TN0030 +tags: [router] +redirectFrom: + - /technotes/TN0030-optimizing-router-builds/ +--- + +While running the GraphOS Router in production has great performance, this comes at the cost of increased build time and higher system requirements when compiling from source. + +Building the router including custom plugins from source is a memory-expensive process, and as such it's not suited for all build environments. + +Some cloud build pipelines such as Google Cloud Build, will require changes to the default build configuration to increase the memory and CPU capacity of the build worker pool. + +The router will also download a large collection of dependencies during the build process each build by default. We can use [Kaniko](https://github.com/GoogleContainerTools/kaniko) to cache intermediate build layers. + +In this example for Google Cloud Build, we have replaced the standard docker [gcr.io/cloud-builders/docker](http://gcr.io/cloud-builders/docker) container image, with [gcr.io/kaniko-project/executor](http://gcr.io/kaniko-project/executor). +This is all that's needed to enable caching of the intermediate build steps. Each step will be pushed to the destination container repo as soon as each layer is built, so even failed builds will contribute to increased build speeds as successful layers are cached. + +We also changed the default `options.machineType` value to `E2_HIGHCPU_8`, this is because the default worker pool doesn't have the CPU or memory resources necessary to compile the router. + +```yaml +#cloudbuild.yaml + +steps: + - id: Build Router + name: 'gcr.io/kaniko-project/executor:latest' + args: + - '--cache=true' + - '--dockerfile=$_DOCKERFILE' + - '--context=dir://$_IMAGE_NAME' + - >- + --destination=$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_IMAGE_NAME:$COMMIT_SHA + - id: Deploy Router + name: 'gcr.io/google.com/cloudsdktool/cloud-sdk:slim' + entrypoint: gcloud + args: + - run + - services + - update + - $_SERVICE_NAME + - '--platform=managed' + - '--image=$_GCR_HOSTNAME/$PROJECT_ID/$REPO_NAME/$_IMAGE_NAME:$COMMIT_SHA' + - '--region=$_DEPLOY_REGION' + - '--quiet' +options: + machineType: E2_HIGHCPU_8 +substitutions: + _DOCKERFILE: custom-router/Dockerfile + _IMAGE_NAME: custom-router + _SERVICE_NAME: apollo-router + _DEPLOY_REGION: northamerica-northeast1 + _GCR_HOSTNAME: northamerica-northeast1-docker.pkg.dev + _PLATFORM: managed +``` diff --git a/docs/source/configuration/health-checks.mdx b/docs/source/routing/self-hosted/health-checks.mdx similarity index 97% rename from docs/source/configuration/health-checks.mdx rename to docs/source/routing/self-hosted/health-checks.mdx index e6f54857d6..6a2566c0c5 100644 --- a/docs/source/configuration/health-checks.mdx +++ b/docs/source/routing/self-hosted/health-checks.mdx @@ -97,7 +97,7 @@ In Kubernetes, you can configure health checks by setting `readinessProbe` and ` port: 8088 # ... snipped for partial example ... ``` -See a more complete example in our [Kubernetes documentation](../containerization/kubernetes/). +See a more complete example in our [Kubernetes documentation](/router/containerization/kubernetes/). ## Using with Docker Docker has a `HEALTHCHECK` instruction that tells Docker how to test whether a container is still working. These are defined in the `Dockerfile` when building your container: ``` diff --git a/docs/source/routing/self-hosted/index.mdx b/docs/source/routing/self-hosted/index.mdx new file mode 100644 index 0000000000..1f7b68e428 --- /dev/null +++ b/docs/source/routing/self-hosted/index.mdx @@ -0,0 +1,49 @@ +--- +title: Self-Hosted Router +subtitle: Host and deploy routers in your own infrastructure +description: Distribute operations efficiently across microservices in your federated GraphQL API with the Apollo GraphOS Router or Apollo Router Core. Configure caching, security features, and more. +--- + +A self-hosted GraphOS Router or Apollo Router Core enables you to fully manage the runtime infrastructure and deployments of your supergraph. + +```mermaid +flowchart LR; + clients(Clients); + subgraph "Your infrastructure"; + router(["Router"]); + serviceB[Products
      API]; + serviceC[Reviews
      API]; + router -->|Sub-query| serviceB & serviceC; + end; + clients -.->|Query| router; + class clients secondary; +``` + + + +Self-hosting the GraphOS Router is limited to [GraphOS Enterprise plans](https://www.apollographql.com/pricing). Other plan types use [managed cloud routing with GraphOS](/graphos/cloud-routing). Check out the [pricing page](https://www.apollographql.com/pricing#graphos-router) to learn more. + + + +## Downloading and installing a self-hosted router + +Apollo provides the router as both a binary and as images to run in your containerized deployments. + +### Router binary + +Apollo provides a binary of the router for multiple platforms. You can download the router bundle, extract the router binary, and run it. + +To learn more, follow the steps in the [self-hosted router installation](/graphos/reference/router/self-hosted-install) reference to run a router binary with a sample supergraph schema. + +### Router container image + +Apollo provides container images of the router to deploy in self-hosted environments. The router images are hosted on GitHub in its container repository. Each router release includes both production and debug images. + +To learn more, go to the [containerization overview](/graphos/routing/self-hosted/containerization). + +- If running with Docker, go to the [Docker](/graphos/routing/self-hosted/containerization/docker) docs to learn how to run router images. +- If running with Kubernetes, go to the [Kubernetes](/graphos/routing/self-hosted/containerization/kubernetes) docs to learn to deploy with router Helm charts. + +## Next steps + +- To prepare your routers for production deployment, follow the guides in [Production Readiness](/graphos/platform/production-readiness/checklist) docs. diff --git a/docs/source/routing/self-hosted/resource-estimator.mdx b/docs/source/routing/self-hosted/resource-estimator.mdx new file mode 100644 index 0000000000..26d8e363d0 --- /dev/null +++ b/docs/source/routing/self-hosted/resource-estimator.mdx @@ -0,0 +1,28 @@ +--- +title: Router Resource Estimator +subtitle: Estimate the system resources to allocate for the GraphOS Router +description: Estimate the system resources you need to allocate for the Apollo GraphOS Router to run production traffic. +published: 2023-12-15 +id: TN0045 +toc: false +tags: [router] +redirectFrom: + - /technotes/TN0045-router_resource_estimator/ +--- + +import RouterResourceEstimator from '../../components/TechNotes/RouterResourceEstimator'; + +The _router resource estimator_ estimates the system resources you need to allocate for the GraphOS Router to run production traffic. The resource estimator can help you get a starting baseline that you can then iterate on. + +## Usage + +To use the estimator: + +1. Enter your estimated **request rate per second** and **peak request rate per second**. +2. Adjust the other parameters to match your estimated production load. + - When selecting the **number of instances**, select fewer for efficiency, more for safety. +3. Be sure to test and iterate. + +## Router resource estimator + + diff --git a/docs/source/routing/self-hosted/resource-management.mdx b/docs/source/routing/self-hosted/resource-management.mdx new file mode 100644 index 0000000000..0e40121313 --- /dev/null +++ b/docs/source/routing/self-hosted/resource-management.mdx @@ -0,0 +1,61 @@ +--- +title: Managing GraphOS Router Resources in Kubernetes +subtitle: Recommendations and considerations for application pods +description: Recommendations and considerations for determining the correct resource requests and limits for application pods in a Kubernetes system. +published: 2022-10-31 +id: TN0016 +tags: [router, kubernetes] +redirectFrom: + - /technotes/TN0016-router-resource-management/ +--- + + + +Self-hosting the GraphOS Router is limited to [GraphOS Enterprise plans](https://www.apollographql.com/pricing). Other plan types use [managed cloud routing with GraphOS](/graphos/cloud-routing). Check out the [pricing page](https://www.apollographql.com/pricing#graphos-router) to learn more. + + + +Determining the correct resource requests and limits for your application pods in a Kubernetes system is not an exact science. Your specific needs depend on many factors, including: + +- The cardinality of unique operation shapes +- The latency of underlying subgraphs and data sources +- The size of responses +- The complexity of query plans + +Our general recommendation for Kubernetes is to start with these requests and limits: + +```yaml +resources: + requests: + memory: '1G' + cpu: '1000m' + limits: + memory: '2G' + # no CPU limit to avoid throttling +``` + + + +The [router resource estimator](/graphos/routing/self-hosted/resource-estimator) is a helpful tool for getting a starting baseline for what resources you may need in production based on your expected traffic. + + + +When using [Horizontal pod autoscaling](https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/), we recommend targeting 90% utilization: + +```yaml +metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 90 + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: 90 +``` + +The GraphOS Router starts up quickly, but when connected to GraphOS the router has to fetch the supergraph schema from Apollo Uplink before it can start serving traffic. We recommend measuring your router's startup time and lowering the `averageUtilization` if your startup time is longer due to Uplink latency or the size of your supergraph schema. From ffec3f902bda97912929d8df9e0a447c936ac2ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e?= Date: Mon, 11 Nov 2024 09:20:36 +0000 Subject: [PATCH 31/77] chore(federation): borrow selection keys (#6074) --- Cargo.lock | 18 + about.toml | 3 +- apollo-federation/Cargo.toml | 1 + apollo-federation/src/operation/contains.rs | 6 +- apollo-federation/src/operation/merging.rs | 17 +- apollo-federation/src/operation/mod.rs | 1035 ++++------------- apollo-federation/src/operation/optimize.rs | 55 +- apollo-federation/src/operation/rebase.rs | 78 +- .../src/operation/selection_map.rs | 647 +++++++++++ apollo-federation/src/operation/simplify.rs | 19 +- apollo-federation/src/operation/tests/mod.rs | 30 +- .../src/query_graph/graph_path.rs | 80 +- .../src/query_graph/path_tree.rs | 5 +- .../src/query_plan/fetch_dependency_graph.rs | 25 +- deny.toml | 3 +- 15 files changed, 1056 insertions(+), 966 deletions(-) create mode 100644 apollo-federation/src/operation/selection_map.rs diff --git a/Cargo.lock b/Cargo.lock index c97f22a4b3..192ac8fc00 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -183,6 +183,7 @@ dependencies = [ "apollo-compiler", "derive_more", "either", + "hashbrown 0.15.0", "hex", "indexmap 2.2.6", "insta", @@ -2577,6 +2578,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" + [[package]] name = "forbid-anonymous-operations" version = "0.1.0" @@ -3085,6 +3092,17 @@ dependencies = [ "allocator-api2", ] +[[package]] +name = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + [[package]] name = "hdrhistogram" version = "7.5.4" diff --git a/about.toml b/about.toml index dbd148a7a4..094647afae 100644 --- a/about.toml +++ b/about.toml @@ -9,7 +9,8 @@ accepted = [ "LicenseRef-ring", "MIT", "MPL-2.0", - "Unicode-DFS-2016" + "Unicode-DFS-2016", + "Zlib" ] # See https://github.com/EmbarkStudios/cargo-about/pull/216 diff --git a/apollo-federation/Cargo.toml b/apollo-federation/Cargo.toml index ce77a6af9e..c93e2d79d0 100644 --- a/apollo-federation/Cargo.toml +++ b/apollo-federation/Cargo.toml @@ -22,6 +22,7 @@ time = { version = "0.3.34", default-features = false, features = [ "local-offset", ] } derive_more = "0.99.17" +hashbrown = "0.15.0" indexmap = { version = "2.2.6", features = ["serde"] } itertools = "0.13.0" lazy_static = "1.4.0" diff --git a/apollo-federation/src/operation/contains.rs b/apollo-federation/src/operation/contains.rs index b734dd304d..904fcdb9d0 100644 --- a/apollo-federation/src/operation/contains.rs +++ b/apollo-federation/src/operation/contains.rs @@ -163,15 +163,15 @@ impl SelectionSet { let mut is_equal = true; let mut did_ignore_typename = false; - for (key, other_selection) in other.selections.iter() { - if key.is_typename_field() && options.ignore_missing_typename { + for other_selection in other.selections.values() { + if other_selection.is_typename_field() && options.ignore_missing_typename { if !self.has_top_level_typename_field() { did_ignore_typename = true; } continue; } - let Some(self_selection) = self.selections.get(key) else { + let Some(self_selection) = self.selections.get(other_selection.key()) else { return Containment::NotContained; }; diff --git a/apollo-federation/src/operation/merging.rs b/apollo-federation/src/operation/merging.rs index e7ebb8b63b..6b8e89193c 100644 --- a/apollo-federation/src/operation/merging.rs +++ b/apollo-federation/src/operation/merging.rs @@ -183,7 +183,7 @@ impl SelectionSet { let target = Arc::make_mut(&mut self.selections); for other_selection in others { let other_key = other_selection.key(); - match target.entry(other_key.clone()) { + match target.entry(other_key) { selection_map::Entry::Occupied(existing) => match existing.get() { Selection::Field(self_field_selection) => { let Selection::Field(other_field_selection) = other_selection else { @@ -193,7 +193,7 @@ impl SelectionSet { ); }; fields - .entry(other_key) + .entry(other_key.to_owned_key()) .or_insert_with(Vec::new) .push(other_field_selection); } @@ -207,7 +207,7 @@ impl SelectionSet { ); }; fragment_spreads - .entry(other_key) + .entry(other_key.to_owned_key()) .or_insert_with(Vec::new) .push(other_fragment_spread_selection); } @@ -226,7 +226,7 @@ impl SelectionSet { ); }; inline_fragments - .entry(other_key) + .entry(other_key.to_owned_key()) .or_insert_with(Vec::new) .push(other_inline_fragment_selection); } @@ -237,10 +237,11 @@ impl SelectionSet { } } - for (key, self_selection) in target.iter_mut() { + for self_selection in target.values_mut() { + let key = self_selection.key().to_owned_key(); match self_selection { SelectionValue::Field(mut self_field_selection) => { - if let Some(other_field_selections) = fields.shift_remove(key) { + if let Some(other_field_selections) = fields.shift_remove(&key) { self_field_selection.merge_into( other_field_selections.iter().map(|selection| &***selection), )?; @@ -248,7 +249,7 @@ impl SelectionSet { } SelectionValue::FragmentSpread(mut self_fragment_spread_selection) => { if let Some(other_fragment_spread_selections) = - fragment_spreads.shift_remove(key) + fragment_spreads.shift_remove(&key) { self_fragment_spread_selection.merge_into( other_fragment_spread_selections @@ -259,7 +260,7 @@ impl SelectionSet { } SelectionValue::InlineFragment(mut self_inline_fragment_selection) => { if let Some(other_inline_fragment_selections) = - inline_fragments.shift_remove(key) + inline_fragments.shift_remove(&key) { self_inline_fragment_selection.merge_into( other_inline_fragment_selections diff --git a/apollo-federation/src/operation/mod.rs b/apollo-federation/src/operation/mod.rs index 2eaacfd4e4..5c0dc7c71f 100644 --- a/apollo-federation/src/operation/mod.rs +++ b/apollo-federation/src/operation/mod.rs @@ -74,7 +74,7 @@ static NEXT_ID: atomic::AtomicUsize = atomic::AtomicUsize::new(1); /// /// Note that we shouldn't add `derive(Serialize, Deserialize)` to this without changing the types /// to be something like UUIDs. -#[derive(Clone, Debug, Eq, PartialEq, Hash)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] // NOTE(@TylerBloom): This feature gate can be removed once the condition in the comment above is // met. Note that there are `serde(skip)` statements that should be removed once this is removed. #[cfg_attr(feature = "snapshot_tracing", derive(Serialize))] @@ -259,434 +259,16 @@ impl PartialEq for SelectionSet { impl Eq for SelectionSet {} -mod selection_map { - use std::borrow::Cow; - use std::iter::Map; - use std::ops::Deref; - use std::sync::Arc; - - use apollo_compiler::collections::IndexMap; - use serde::Serialize; - - use crate::error::FederationError; - use crate::error::SingleFederationError::Internal; - use crate::operation::field_selection::FieldSelection; - use crate::operation::fragment_spread_selection::FragmentSpreadSelection; - use crate::operation::inline_fragment_selection::InlineFragmentSelection; - use crate::operation::HasSelectionKey; - use crate::operation::Selection; - use crate::operation::SelectionKey; - use crate::operation::SelectionSet; - use crate::operation::SiblingTypename; - - /// A "normalized" selection map is an optimized representation of a selection set which does - /// not contain selections with the same selection "key". Selections that do have the same key - /// are merged during the normalization process. By storing a selection set as a map, we can - /// efficiently merge/join multiple selection sets. - /// - /// Because the key depends strictly on the value, we expose the underlying map's API in a - /// read-only capacity, while mutations use an API closer to `IndexSet`. We don't just use an - /// `IndexSet` since key computation is expensive (it involves sorting). This type is in its own - /// module to prevent code from accidentally mutating the underlying map outside the mutation - /// API. - #[derive(Debug, Clone, PartialEq, Eq, Default, Serialize)] - pub(crate) struct SelectionMap(IndexMap); - - impl Deref for SelectionMap { - type Target = IndexMap; - - fn deref(&self) -> &Self::Target { - &self.0 - } - } - - impl SelectionMap { - pub(crate) fn new() -> Self { - SelectionMap(IndexMap::default()) - } - - #[cfg(test)] - pub(crate) fn clear(&mut self) { - self.0.clear(); - } - - pub(crate) fn insert(&mut self, value: Selection) -> Option { - self.0.insert(value.key(), value) - } - - /// Remove a selection from the map. Returns the selection and its numeric index. - pub(crate) fn remove(&mut self, key: &SelectionKey) -> Option<(usize, Selection)> { - // We specifically use shift_remove() instead of swap_remove() to maintain order. - self.0 - .shift_remove_full(key) - .map(|(index, _key, selection)| (index, selection)) - } - - pub(crate) fn retain( - &mut self, - mut predicate: impl FnMut(&SelectionKey, &Selection) -> bool, - ) { - self.0.retain(|k, v| predicate(k, v)) - } - - pub(crate) fn get_mut(&mut self, key: &SelectionKey) -> Option { - self.0.get_mut(key).map(SelectionValue::new) - } - - pub(crate) fn iter_mut(&mut self) -> IterMut { - self.0.iter_mut().map(|(k, v)| (k, SelectionValue::new(v))) - } - - pub(super) fn entry(&mut self, key: SelectionKey) -> Entry { - match self.0.entry(key) { - indexmap::map::Entry::Occupied(entry) => Entry::Occupied(OccupiedEntry(entry)), - indexmap::map::Entry::Vacant(entry) => Entry::Vacant(VacantEntry(entry)), - } - } - - pub(crate) fn extend(&mut self, other: SelectionMap) { - self.0.extend(other.0) - } - - pub(crate) fn extend_ref(&mut self, other: &SelectionMap) { - self.0 - .extend(other.iter().map(|(k, v)| (k.clone(), v.clone()))) - } - - /// Returns the selection set resulting from "recursively" filtering any selection - /// that does not match the provided predicate. - /// This method calls `predicate` on every selection of the selection set, - /// not just top-level ones, and apply a "depth-first" strategy: - /// when the predicate is called on a given selection it is guaranteed that - /// filtering has happened on all the selections of its sub-selection. - pub(crate) fn filter_recursive_depth_first( - &self, - predicate: &mut dyn FnMut(&Selection) -> Result, - ) -> Result, FederationError> { - fn recur_sub_selections<'sel>( - selection: &'sel Selection, - predicate: &mut dyn FnMut(&Selection) -> Result, - ) -> Result, FederationError> { - Ok(match selection { - Selection::Field(field) => { - if let Some(sub_selections) = &field.selection_set { - match sub_selections.filter_recursive_depth_first(predicate)? { - Cow::Borrowed(_) => Cow::Borrowed(selection), - Cow::Owned(new) => Cow::Owned(Selection::from_field( - field.field.clone(), - Some(new), - )), - } - } else { - Cow::Borrowed(selection) - } - } - Selection::InlineFragment(fragment) => match fragment - .selection_set - .filter_recursive_depth_first(predicate)? - { - Cow::Borrowed(_) => Cow::Borrowed(selection), - Cow::Owned(selection_set) => Cow::Owned(Selection::InlineFragment( - Arc::new(InlineFragmentSelection::new( - fragment.inline_fragment.clone(), - selection_set, - )), - )), - }, - Selection::FragmentSpread(_) => { - return Err(FederationError::internal("unexpected fragment spread")) - } - }) - } - let mut iter = self.0.iter(); - let mut enumerated = (&mut iter).enumerate(); - let mut new_map: IndexMap<_, _>; - loop { - let Some((index, (key, selection))) = enumerated.next() else { - return Ok(Cow::Borrowed(self)); - }; - let filtered = recur_sub_selections(selection, predicate)?; - let keep = predicate(&filtered)?; - if keep && matches!(filtered, Cow::Borrowed(_)) { - // Nothing changed so far, continue without cloning - continue; - } - - // Clone the map so far - new_map = self.0.as_slice()[..index] - .iter() - .map(|(k, v)| (k.clone(), v.clone())) - .collect(); - - if keep { - new_map.insert(key.clone(), filtered.into_owned()); - } - break; - } - for (key, selection) in iter { - let filtered = recur_sub_selections(selection, predicate)?; - if predicate(&filtered)? { - new_map.insert(key.clone(), filtered.into_owned()); - } - } - Ok(Cow::Owned(Self(new_map))) - } - } - - impl
      FromIterator for SelectionMap - where - A: Into, - { - fn from_iter>(iter: T) -> Self { - let mut map = Self::new(); - for selection in iter { - map.insert(selection.into()); - } - map - } - } - - type IterMut<'a> = Map< - indexmap::map::IterMut<'a, SelectionKey, Selection>, - fn((&'a SelectionKey, &'a mut Selection)) -> (&'a SelectionKey, SelectionValue<'a>), - >; - - /// A mutable reference to a `Selection` value in a `SelectionMap`, which - /// also disallows changing key-related data (to maintain the invariant that a value's key is - /// the same as it's map entry's key). - #[derive(Debug)] - pub(crate) enum SelectionValue<'a> { - Field(FieldSelectionValue<'a>), - FragmentSpread(FragmentSpreadSelectionValue<'a>), - InlineFragment(InlineFragmentSelectionValue<'a>), - } - - impl<'a> SelectionValue<'a> { - pub(crate) fn new(selection: &'a mut Selection) -> Self { - match selection { - Selection::Field(field_selection) => { - SelectionValue::Field(FieldSelectionValue::new(field_selection)) - } - Selection::FragmentSpread(fragment_spread_selection) => { - SelectionValue::FragmentSpread(FragmentSpreadSelectionValue::new( - fragment_spread_selection, - )) - } - Selection::InlineFragment(inline_fragment_selection) => { - SelectionValue::InlineFragment(InlineFragmentSelectionValue::new( - inline_fragment_selection, - )) - } - } - } - - #[cfg(test)] - pub(super) fn get_selection_set_mut(&mut self) -> Option<&mut SelectionSet> { - match self { - Self::Field(field) => field.get_selection_set_mut().as_mut(), - Self::FragmentSpread(spread) => Some(spread.get_selection_set_mut()), - Self::InlineFragment(inline) => Some(inline.get_selection_set_mut()), - } - } - } - - #[derive(Debug)] - pub(crate) struct FieldSelectionValue<'a>(&'a mut Arc); - - impl<'a> FieldSelectionValue<'a> { - pub(crate) fn new(field_selection: &'a mut Arc) -> Self { - Self(field_selection) - } - - pub(crate) fn get(&self) -> &Arc { - self.0 - } - - pub(crate) fn get_sibling_typename_mut(&mut self) -> &mut Option { - Arc::make_mut(self.0).field.sibling_typename_mut() - } - - pub(crate) fn get_selection_set_mut(&mut self) -> &mut Option { - &mut Arc::make_mut(self.0).selection_set - } - } - - #[derive(Debug)] - pub(crate) struct FragmentSpreadSelectionValue<'a>(&'a mut Arc); - - impl<'a> FragmentSpreadSelectionValue<'a> { - pub(crate) fn new(fragment_spread_selection: &'a mut Arc) -> Self { - Self(fragment_spread_selection) - } - - #[cfg(test)] - pub(crate) fn get_selection_set_mut(&mut self) -> &mut SelectionSet { - &mut Arc::make_mut(self.0).selection_set - } - - pub(crate) fn get(&self) -> &Arc { - self.0 - } - } - - #[derive(Debug)] - pub(crate) struct InlineFragmentSelectionValue<'a>(&'a mut Arc); - - impl<'a> InlineFragmentSelectionValue<'a> { - pub(crate) fn new(inline_fragment_selection: &'a mut Arc) -> Self { - Self(inline_fragment_selection) - } - - pub(crate) fn get(&self) -> &Arc { - self.0 - } - - pub(crate) fn get_selection_set_mut(&mut self) -> &mut SelectionSet { - &mut Arc::make_mut(self.0).selection_set - } - } - - pub(crate) enum Entry<'a> { - Occupied(OccupiedEntry<'a>), - Vacant(VacantEntry<'a>), - } - - impl<'a> Entry<'a> { - pub(crate) fn or_insert( - self, - produce: impl FnOnce() -> Result, - ) -> Result, FederationError> { - match self { - Self::Occupied(entry) => Ok(entry.into_mut()), - Self::Vacant(entry) => entry.insert(produce()?), - } - } - } - - pub(crate) struct OccupiedEntry<'a>(indexmap::map::OccupiedEntry<'a, SelectionKey, Selection>); - - impl<'a> OccupiedEntry<'a> { - pub(crate) fn get(&self) -> &Selection { - self.0.get() - } - - pub(crate) fn into_mut(self) -> SelectionValue<'a> { - SelectionValue::new(self.0.into_mut()) - } - } - - pub(crate) struct VacantEntry<'a>(indexmap::map::VacantEntry<'a, SelectionKey, Selection>); - - impl<'a> VacantEntry<'a> { - pub(crate) fn key(&self) -> &SelectionKey { - self.0.key() - } - - pub(crate) fn insert( - self, - value: Selection, - ) -> Result, FederationError> { - if *self.key() != value.key() { - return Err(Internal { - message: format!( - "Key mismatch when inserting selection {} into vacant entry ", - value - ), - } - .into()); - } - Ok(SelectionValue::new(self.0.insert(value))) - } - } - - impl IntoIterator for SelectionMap { - type Item = as IntoIterator>::Item; - type IntoIter = as IntoIterator>::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - as IntoIterator>::into_iter(self.0) - } - } - - impl<'a> IntoIterator for &'a SelectionMap { - type Item = <&'a IndexMap as IntoIterator>::Item; - type IntoIter = <&'a IndexMap as IntoIterator>::IntoIter; - - fn into_iter(self) -> Self::IntoIter { - self.0.iter() - } - } -} +mod selection_map; pub(crate) use selection_map::FieldSelectionValue; pub(crate) use selection_map::FragmentSpreadSelectionValue; +pub(crate) use selection_map::HasSelectionKey; pub(crate) use selection_map::InlineFragmentSelectionValue; +pub(crate) use selection_map::SelectionKey; pub(crate) use selection_map::SelectionMap; pub(crate) use selection_map::SelectionValue; -/// A selection "key" (unrelated to the federation `@key` directive) is an identifier of a selection -/// (field, inline fragment, or fragment spread) that is used to determine whether two selections -/// can be merged. -/// -/// In order to merge two selections they need to -/// * reference the same field/inline fragment -/// * specify the same directives -/// * directives have to be applied in the same order -/// * directive arguments order does not matter (they get automatically sorted by their names). -/// * selection cannot specify @defer directive -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)] -pub(crate) enum SelectionKey { - Field { - /// The field alias (if specified) or field name in the resulting selection set. - response_name: Name, - /// directives applied on the field - #[serde(serialize_with = "crate::display_helpers::serialize_as_string")] - directives: DirectiveList, - }, - FragmentSpread { - /// The name of the fragment. - fragment_name: Name, - /// Directives applied on the fragment spread (does not contain @defer). - #[serde(serialize_with = "crate::display_helpers::serialize_as_string")] - directives: DirectiveList, - }, - InlineFragment { - /// The optional type condition of the fragment. - type_condition: Option, - /// Directives applied on the fragment spread (does not contain @defer). - #[serde(serialize_with = "crate::display_helpers::serialize_as_string")] - directives: DirectiveList, - }, - Defer { - /// Unique selection ID used to distinguish deferred fragment spreads that cannot be merged. - #[cfg_attr(not(feature = "snapshot_tracing"), serde(skip))] - deferred_id: SelectionId, - }, -} - -impl SelectionKey { - /// Returns true if the selection key is `__typename` *without directives*. - pub(crate) fn is_typename_field(&self) -> bool { - matches!(self, SelectionKey::Field { response_name, directives } if *response_name == TYPENAME_FIELD && directives.is_empty()) - } - - /// Create a selection key for a specific field name. - /// - /// This is available for tests only as selection keys should not normally be created outside of - /// `HasSelectionKey::key`. - #[cfg(test)] - pub(crate) fn field_name(name: &str) -> Self { - SelectionKey::Field { - response_name: Name::new(name).unwrap(), - directives: Default::default(), - } - } -} - -pub(crate) trait HasSelectionKey { - fn key(&self) -> SelectionKey; -} - /// An analogue of the apollo-compiler type `Selection` that stores our other selection analogues /// instead of the apollo-compiler types. #[derive(Debug, Clone, PartialEq, Eq, derive_more::IsVariant, Serialize)] @@ -822,6 +404,17 @@ impl Selection { } } + /// Returns true if the selection key is `__typename` *without directives*. + pub(crate) fn is_typename_field(&self) -> bool { + if let Selection::Field(field) = self { + *field.field.response_name() == TYPENAME_FIELD && field.field.directives.is_empty() + } else { + false + } + } + + /// Returns the conditions for inclusion of this selection. + /// /// # Errors /// Returns an error if the selection contains a fragment spread, or if any of the /// @skip/@include directives are invalid (per GraphQL validation rules). @@ -937,7 +530,7 @@ impl From for Selection { } impl HasSelectionKey for Selection { - fn key(&self) -> SelectionKey { + fn key(&self) -> SelectionKey<'_> { match self { Selection::Field(field_selection) => field_selection.key(), Selection::FragmentSpread(fragment_spread_selection) => fragment_spread_selection.key(), @@ -990,7 +583,6 @@ impl Fragment { mod field_selection { use std::hash::Hash; use std::hash::Hasher; - use std::ops::Deref; use apollo_compiler::Name; use serde::Serialize; @@ -1024,7 +616,7 @@ mod field_selection { } impl HasSelectionKey for FieldSelection { - fn key(&self) -> SelectionKey { + fn key(&self) -> SelectionKey<'_> { self.field.key() } } @@ -1039,33 +631,46 @@ mod field_selection { selection_set, } } + } - pub(crate) fn with_updated_alias(&self, alias: Name) -> Field { - let mut data = self.field.data().clone(); - data.alias = Some(alias); - Field::new(data) + // SiblingTypename indicates how the sibling __typename field should be restored. + // PORT_NOTE: The JS version used the empty string to indicate unaliased sibling typenames. + // Here we use an enum to make the distinction explicit. + #[derive(Debug, Clone, Serialize)] + pub(crate) enum SiblingTypename { + Unaliased, + Aliased(Name), // the sibling __typename has been aliased + } + + impl SiblingTypename { + pub(crate) fn alias(&self) -> Option<&Name> { + match self { + SiblingTypename::Unaliased => None, + SiblingTypename::Aliased(alias) => Some(alias), + } } } /// The non-selection-set data of `FieldSelection`, used with operation paths and graph /// paths. - #[derive(Clone, Serialize)] + #[derive(Debug, Clone, Serialize)] pub(crate) struct Field { - data: FieldData, - key: SelectionKey, - } - - impl std::fmt::Debug for Field { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.data.fmt(f) - } + #[serde(skip)] + pub(crate) schema: ValidFederationSchema, + pub(crate) field_position: FieldDefinitionPosition, + pub(crate) alias: Option, + #[serde(serialize_with = "crate::display_helpers::serialize_as_debug_string")] + pub(crate) arguments: ArgumentList, + #[serde(serialize_with = "crate::display_helpers::serialize_as_string")] + pub(crate) directives: DirectiveList, + pub(crate) sibling_typename: Option, } impl PartialEq for Field { fn eq(&self, other: &Self) -> bool { - self.data.field_position.field_name() == other.data.field_position.field_name() - && self.key == other.key - && self.data.arguments == other.data.arguments + self.field_position.field_name() == other.field_position.field_name() + && self.key() == other.key() + && self.arguments == other.arguments } } @@ -1073,25 +678,26 @@ mod field_selection { impl Hash for Field { fn hash(&self, state: &mut H) { - self.data.field_position.field_name().hash(state); - self.key.hash(state); - self.data.arguments.hash(state); - } - } - - impl Deref for Field { - type Target = FieldData; - - fn deref(&self) -> &Self::Target { - &self.data + self.field_position.field_name().hash(state); + self.key().hash(state); + self.arguments.hash(state); } } impl Field { - pub(crate) fn new(data: FieldData) -> Self { + /// Create a trivial field selection without any arguments or directives. + #[cfg(test)] + pub(crate) fn from_position( + schema: &ValidFederationSchema, + field_position: FieldDefinitionPosition, + ) -> Self { Self { - key: data.key(), - data, + schema: schema.clone(), + field_position, + alias: None, + arguments: Default::default(), + directives: Default::default(), + sibling_typename: None, } } @@ -1102,14 +708,73 @@ mod field_selection { parent_type: &CompositeTypeDefinitionPosition, alias: Option, ) -> Self { - Self::new(FieldData { + Self { schema: schema.clone(), field_position: parent_type.introspection_typename_field(), alias, arguments: Default::default(), directives: Default::default(), sibling_typename: None, - }) + } + } + + pub(crate) fn schema(&self) -> &ValidFederationSchema { + &self.schema + } + + pub(crate) fn name(&self) -> &Name { + self.field_position.field_name() + } + + pub(crate) fn response_name(&self) -> &Name { + self.alias.as_ref().unwrap_or_else(|| self.name()) + } + + // Is this a plain simple __typename without any directive or alias? + pub(crate) fn is_plain_typename_field(&self) -> bool { + *self.field_position.field_name() == TYPENAME_FIELD + && self.directives.is_empty() + && self.alias.is_none() + } + + pub(crate) fn sibling_typename(&self) -> Option<&SiblingTypename> { + self.sibling_typename.as_ref() + } + + pub(crate) fn sibling_typename_mut(&mut self) -> &mut Option { + &mut self.sibling_typename + } + + pub(crate) fn as_path_element(&self) -> FetchDataPathElement { + FetchDataPathElement::Key(self.response_name().clone(), Default::default()) + } + + pub(crate) fn output_base_type(&self) -> Result { + let definition = self.field_position.get(self.schema.schema())?; + self.schema + .get_type(definition.ty.inner_named_type().clone()) + } + + pub(crate) fn is_leaf(&self) -> Result { + let base_type_position = self.output_base_type()?; + Ok(matches!( + base_type_position, + TypeDefinitionPosition::Scalar(_) | TypeDefinitionPosition::Enum(_) + )) + } + + pub(crate) fn with_updated_directives(&self, directives: impl Into) -> Self { + Self { + directives: directives.into(), + ..self.clone() + } + } + + pub(crate) fn with_updated_alias(&self, alias: Name) -> Self { + Self { + alias: Some(alias), + ..self.clone() + } } /// Turn this `Field` into a `FieldSelection` with the given sub-selection. If this is @@ -1120,7 +785,7 @@ mod field_selection { ) -> FieldSelection { if cfg!(debug_assertions) { if let Some(ref selection_set) = selection_set { - if let Ok(field_type) = self.data.output_base_type() { + if let Ok(field_type) = self.output_base_type() { if let Ok(field_type_position) = CompositeTypeDefinitionPosition::try_from(field_type) { @@ -1153,139 +818,23 @@ mod field_selection { selection_set, } } - - pub(crate) fn schema(&self) -> &ValidFederationSchema { - &self.data.schema - } - - pub(crate) fn data(&self) -> &FieldData { - &self.data - } - - // Is this a plain simple __typename without any directive or alias? - pub(crate) fn is_plain_typename_field(&self) -> bool { - *self.data.field_position.field_name() == TYPENAME_FIELD - && self.data.directives.is_empty() - && self.data.alias.is_none() - } - - pub(crate) fn sibling_typename(&self) -> Option<&SiblingTypename> { - self.data.sibling_typename.as_ref() - } - - pub(crate) fn sibling_typename_mut(&mut self) -> &mut Option { - &mut self.data.sibling_typename - } - - pub(crate) fn with_updated_directives( - &self, - directives: impl Into, - ) -> Field { - let mut data = self.data.clone(); - data.directives = directives.into(); - Self::new(data) - } - - pub(crate) fn as_path_element(&self) -> FetchDataPathElement { - FetchDataPathElement::Key(self.response_name(), Default::default()) - } } impl HasSelectionKey for Field { - fn key(&self) -> SelectionKey { - self.key.clone() - } - } - - // SiblingTypename indicates how the sibling __typename field should be restored. - // PORT_NOTE: The JS version used the empty string to indicate unaliased sibling typenames. - // Here we use an enum to make the distinction explicit. - #[derive(Debug, Clone, Serialize)] - pub(crate) enum SiblingTypename { - Unaliased, - Aliased(Name), // the sibling __typename has been aliased - } - - impl SiblingTypename { - pub(crate) fn alias(&self) -> Option<&Name> { - match self { - SiblingTypename::Unaliased => None, - SiblingTypename::Aliased(alias) => Some(alias), - } - } - } - - #[derive(Debug, Clone, Serialize)] - pub(crate) struct FieldData { - #[serde(skip)] - pub(crate) schema: ValidFederationSchema, - pub(crate) field_position: FieldDefinitionPosition, - pub(crate) alias: Option, - #[serde(serialize_with = "crate::display_helpers::serialize_as_debug_string")] - pub(crate) arguments: ArgumentList, - #[serde(serialize_with = "crate::display_helpers::serialize_as_string")] - pub(crate) directives: DirectiveList, - pub(crate) sibling_typename: Option, - } - - impl FieldData { - #[cfg(test)] - /// Create a trivial field selection without any arguments or directives. - pub(crate) fn from_position( - schema: &ValidFederationSchema, - field_position: FieldDefinitionPosition, - ) -> Self { - Self { - schema: schema.clone(), - field_position, - alias: None, - arguments: Default::default(), - directives: Default::default(), - sibling_typename: None, - } - } - - pub(crate) fn name(&self) -> &Name { - self.field_position.field_name() - } - - pub(crate) fn response_name(&self) -> Name { - self.alias.clone().unwrap_or_else(|| self.name().clone()) - } - - pub(crate) fn output_base_type(&self) -> Result { - let definition = self.field_position.get(self.schema.schema())?; - self.schema - .get_type(definition.ty.inner_named_type().clone()) - } - - pub(crate) fn is_leaf(&self) -> Result { - let base_type_position = self.output_base_type()?; - Ok(matches!( - base_type_position, - TypeDefinitionPosition::Scalar(_) | TypeDefinitionPosition::Enum(_) - )) - } - } - - impl HasSelectionKey for FieldData { - fn key(&self) -> SelectionKey { + fn key(&self) -> SelectionKey<'_> { SelectionKey::Field { response_name: self.response_name(), - directives: self.directives.clone(), + directives: &self.directives, } } } } pub(crate) use field_selection::Field; -pub(crate) use field_selection::FieldData; pub(crate) use field_selection::FieldSelection; pub(crate) use field_selection::SiblingTypename; mod fragment_spread_selection { - use std::ops::Deref; - use apollo_compiler::Name; use serde::Serialize; @@ -1305,7 +854,7 @@ mod fragment_spread_selection { } impl HasSelectionKey for FragmentSpreadSelection { - fn key(&self) -> SelectionKey { + fn key(&self) -> SelectionKey<'_> { self.spread.key() } } @@ -1313,55 +862,8 @@ mod fragment_spread_selection { /// An analogue of the apollo-compiler type `FragmentSpread` with these changes: /// - Stores the schema (may be useful for directives). /// - Encloses collection types in `Arc`s to facilitate cheaper cloning. - #[derive(Clone, Serialize)] - pub(crate) struct FragmentSpread { - data: FragmentSpreadData, - key: SelectionKey, - } - - impl std::fmt::Debug for FragmentSpread { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.data.fmt(f) - } - } - - impl PartialEq for FragmentSpread { - fn eq(&self, other: &Self) -> bool { - self.key == other.key - } - } - - impl Eq for FragmentSpread {} - - impl Deref for FragmentSpread { - type Target = FragmentSpreadData; - - fn deref(&self) -> &Self::Target { - &self.data - } - } - - impl FragmentSpread { - pub(crate) fn new(data: FragmentSpreadData) -> Self { - Self { - key: data.key(), - data, - } - } - - pub(crate) fn data(&self) -> &FragmentSpreadData { - &self.data - } - } - - impl HasSelectionKey for FragmentSpread { - fn key(&self) -> SelectionKey { - self.key.clone() - } - } - #[derive(Debug, Clone, Serialize)] - pub(crate) struct FragmentSpreadData { + pub(crate) struct FragmentSpread { #[serde(skip)] pub(crate) schema: ValidFederationSchema, pub(crate) fragment_name: Name, @@ -1380,16 +882,24 @@ mod fragment_spread_selection { pub(crate) selection_id: SelectionId, } - impl HasSelectionKey for FragmentSpreadData { - fn key(&self) -> SelectionKey { + impl PartialEq for FragmentSpread { + fn eq(&self, other: &Self) -> bool { + self.key() == other.key() + } + } + + impl Eq for FragmentSpread {} + + impl HasSelectionKey for FragmentSpread { + fn key(&self) -> SelectionKey<'_> { if is_deferred_selection(&self.directives) { SelectionKey::Defer { - deferred_id: self.selection_id.clone(), + deferred_id: self.selection_id, } } else { SelectionKey::FragmentSpread { - fragment_name: self.fragment_name.clone(), - directives: self.directives.clone(), + fragment_name: &self.fragment_name, + directives: &self.directives, } } } @@ -1397,7 +907,6 @@ mod fragment_spread_selection { } pub(crate) use fragment_spread_selection::FragmentSpread; -pub(crate) use fragment_spread_selection::FragmentSpreadData; pub(crate) use fragment_spread_selection::FragmentSpreadSelection; impl FragmentSpreadSelection { @@ -1410,9 +919,9 @@ impl FragmentSpreadSelection { fragment_spread: &executable::FragmentSpread, fragment: &Node, ) -> Result { - let spread_data = FragmentSpreadData::from_fragment(fragment, &fragment_spread.directives); + let spread = FragmentSpread::from_fragment(fragment, &fragment_spread.directives); Ok(FragmentSpreadSelection { - spread: FragmentSpread::new(spread_data), + spread, selection_set: fragment.selection_set.clone(), }) } @@ -1421,9 +930,9 @@ impl FragmentSpreadSelection { fragment: &Node, directives: &executable::DirectiveList, ) -> Self { - let spread_data = FragmentSpreadData::from_fragment(fragment, directives); + let spread = FragmentSpread::from_fragment(fragment, directives); Self { - spread: FragmentSpread::new(spread_data), + spread, selection_set: fragment.selection_set.clone(), } } @@ -1450,13 +959,13 @@ impl FragmentSpreadSelection { parent_type_position: CompositeTypeDefinitionPosition, predicate: &mut impl FnMut(OpPathElement) -> Result, ) -> Result { - let inline_fragment = InlineFragment::new(InlineFragmentData { + let inline_fragment = InlineFragment { schema: self.spread.schema.clone(), parent_type_position, type_condition_position: Some(self.spread.type_condition_position.clone()), directives: self.spread.directives.clone(), - selection_id: self.spread.selection_id.clone(), - }); + selection_id: self.spread.selection_id, + }; if predicate(inline_fragment.into())? { return Ok(true); } @@ -1464,12 +973,12 @@ impl FragmentSpreadSelection { } } -impl FragmentSpreadData { +impl FragmentSpread { pub(crate) fn from_fragment( fragment: &Node, spread_directives: &executable::DirectiveList, - ) -> FragmentSpreadData { - FragmentSpreadData { + ) -> FragmentSpread { + FragmentSpread { schema: fragment.schema.clone(), fragment_name: fragment.name.clone(), type_condition_position: fragment.type_condition_position.clone(), @@ -1483,7 +992,6 @@ impl FragmentSpreadData { mod inline_fragment_selection { use std::hash::Hash; use std::hash::Hasher; - use std::ops::Deref; use serde::Serialize; @@ -1542,28 +1050,28 @@ mod inline_fragment_selection { } impl HasSelectionKey for InlineFragmentSelection { - fn key(&self) -> SelectionKey { + fn key(&self) -> SelectionKey<'_> { self.inline_fragment.key() } } /// The non-selection-set data of `InlineFragmentSelection`, used with operation paths and /// graph paths. - #[derive(Clone, Serialize)] + #[derive(Debug, Clone, Serialize)] pub(crate) struct InlineFragment { - data: InlineFragmentData, - key: SelectionKey, - } - - impl std::fmt::Debug for InlineFragment { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.data.fmt(f) - } + #[serde(skip)] + pub(crate) schema: ValidFederationSchema, + pub(crate) parent_type_position: CompositeTypeDefinitionPosition, + pub(crate) type_condition_position: Option, + #[serde(serialize_with = "crate::display_helpers::serialize_as_string")] + pub(crate) directives: DirectiveList, + #[cfg_attr(not(feature = "snapshot_tracing"), serde(skip))] + pub(crate) selection_id: SelectionId, } impl PartialEq for InlineFragment { fn eq(&self, other: &Self) -> bool { - self.key == other.key + self.key() == other.key() } } @@ -1571,49 +1079,30 @@ mod inline_fragment_selection { impl Hash for InlineFragment { fn hash(&self, state: &mut H) { - self.key.hash(state); - } - } - - impl Deref for InlineFragment { - type Target = InlineFragmentData; - - fn deref(&self) -> &Self::Target { - &self.data + self.key().hash(state); } } impl InlineFragment { - pub(crate) fn new(data: InlineFragmentData) -> Self { - Self { - key: data.key(), - data, - } - } - pub(crate) fn schema(&self) -> &ValidFederationSchema { - &self.data.schema - } - - pub(crate) fn data(&self) -> &InlineFragmentData { - &self.data + &self.schema } pub(crate) fn with_updated_type_condition( &self, - new: Option, + type_condition_position: Option, ) -> Self { - let mut data = self.data().clone(); - data.type_condition_position = new; - Self::new(data) + Self { + type_condition_position, + ..self.clone() + } } - pub(crate) fn with_updated_directives( - &self, - directives: impl Into, - ) -> InlineFragment { - let mut data = self.data().clone(); - data.directives = directives.into(); - Self::new(data) + + pub(crate) fn with_updated_directives(&self, directives: impl Into) -> Self { + Self { + directives: directives.into(), + ..self.clone() + } } pub(crate) fn as_path_element(&self) -> Option { @@ -1623,27 +1112,7 @@ mod inline_fragment_selection { condition.type_name().clone(), )) } - } - - impl HasSelectionKey for InlineFragment { - fn key(&self) -> SelectionKey { - self.key.clone() - } - } - #[derive(Debug, Clone, Serialize)] - pub(crate) struct InlineFragmentData { - #[serde(skip)] - pub(crate) schema: ValidFederationSchema, - pub(crate) parent_type_position: CompositeTypeDefinitionPosition, - pub(crate) type_condition_position: Option, - #[serde(serialize_with = "crate::display_helpers::serialize_as_string")] - pub(crate) directives: DirectiveList, - #[cfg_attr(not(feature = "snapshot_tracing"), serde(skip))] - pub(crate) selection_id: SelectionId, - } - - impl InlineFragmentData { pub(crate) fn defer_directive_arguments( &self, ) -> Result, FederationError> { @@ -1661,19 +1130,19 @@ mod inline_fragment_selection { } } - impl HasSelectionKey for InlineFragmentData { - fn key(&self) -> SelectionKey { + impl HasSelectionKey for InlineFragment { + fn key(&self) -> SelectionKey<'_> { if is_deferred_selection(&self.directives) { SelectionKey::Defer { - deferred_id: self.selection_id.clone(), + deferred_id: self.selection_id, } } else { SelectionKey::InlineFragment { type_condition: self .type_condition_position .as_ref() - .map(|pos| pos.type_name().clone()), - directives: self.directives.clone(), + .map(|pos| pos.type_name()), + directives: &self.directives, } } } @@ -1681,9 +1150,9 @@ mod inline_fragment_selection { } pub(crate) use inline_fragment_selection::InlineFragment; -pub(crate) use inline_fragment_selection::InlineFragmentData; pub(crate) use inline_fragment_selection::InlineFragmentSelection; +use self::selection_map::OwnedSelectionKey; use crate::schema::position::INTROSPECTION_TYPENAME_FIELD_NAME; /// A simple MultiMap implementation using IndexMap with Vec as its value type. @@ -1751,7 +1220,7 @@ impl SelectionSet { // one :( struct TopLevelFieldSplitter { parent_type: CompositeTypeDefinitionPosition, - starting_set: ::IntoIter, + starting_set: selection_map::IntoValues, stack: Vec<(OpPathElement, Self)>, } @@ -1759,7 +1228,7 @@ impl SelectionSet { fn new(selection_set: SelectionSet) -> Self { Self { parent_type: selection_set.type_position, - starting_set: Arc::unwrap_or_clone(selection_set.selections).into_iter(), + starting_set: Arc::unwrap_or_clone(selection_set.selections).into_values(), stack: Vec::new(), } } @@ -1772,7 +1241,7 @@ impl SelectionSet { loop { match self.stack.last_mut() { None => { - let selection = self.starting_set.next()?.1; + let selection = self.starting_set.next()?; if selection.is_field() { return Some(SelectionSet::from_selection( self.parent_type.clone(), @@ -1868,7 +1337,7 @@ impl SelectionSet { } pub(crate) fn contains_top_level_field(&self, field: &Field) -> Result { - if let Some(selection) = self.selections.get(&field.key()) { + if let Some(selection) = self.selections.get(field.key()) { let Selection::Field(field_selection) = selection else { return Err(SingleFederationError::Internal { message: format!( @@ -2020,7 +1489,7 @@ impl SelectionSet { destination: &mut Vec, selection_set: &SelectionSet, ) -> Result<(), FederationError> { - for (_, value) in selection_set.selections.iter() { + for value in selection_set.selections.values() { match value { Selection::Field(field_selection) => { let selections = match &field_selection.selection_set { @@ -2104,20 +1573,21 @@ impl SelectionSet { interface_types_with_interface_objects.contains(&InterfaceTypeDefinitionPosition { type_name: self.type_position.type_name().clone(), }); - let mut typename_field_key: Option = None; - let mut sibling_field_key: Option = None; + let mut typename_field_key: Option = None; + let mut sibling_field_key: Option = None; let mutable_selection_map = Arc::make_mut(&mut self.selections); - for (key, entry) in mutable_selection_map.iter_mut() { + for entry in mutable_selection_map.values_mut() { + let key = entry.key().to_owned_key(); match entry { SelectionValue::Field(mut field_selection) => { if field_selection.get().field.is_plain_typename_field() && !is_interface_object && typename_field_key.is_none() { - typename_field_key = Some(key.clone()); + typename_field_key = Some(key); } else if sibling_field_key.is_none() { - sibling_field_key = Some(key.clone()); + sibling_field_key = Some(key); } if let Some(field_selection_set) = field_selection.get_selection_set_mut() { @@ -2149,8 +1619,8 @@ impl SelectionSet { Some((_, Selection::Field(typename_field))), Some(SelectionValue::Field(mut sibling_field)), ) = ( - mutable_selection_map.remove(&typename_key), - mutable_selection_map.get_mut(&sibling_field_key), + mutable_selection_map.remove(typename_key.as_borrowed_key()), + mutable_selection_map.get_mut(sibling_field_key.as_borrowed_key()), ) { // Note that as we tag the element, we also record the alias used if any since that // needs to be preserved. @@ -2199,6 +1669,13 @@ impl SelectionSet { } } + /// Returns the conditions for inclusion of this selection set. + /// + /// This tries to be smart about including or excluding the whole selection set. + /// - If all selections have the same condition, returns that condition. + /// - If selections in the set have different conditions, the selection set must always be + /// included, so the individual selections can be evaluated. + /// /// # Errors /// Returns an error if the selection set contains a fragment spread, or if any of the /// @skip/@include directives are invalid (per GraphQL validation rules). @@ -2272,8 +1749,8 @@ impl SelectionSet { sub_selection_updates.extend( sub_selection_set .selections - .iter() - .map(|(k, v)| (k.clone(), v.clone())), + .values() + .map(|v| (v.key(), v.clone())), ); } } @@ -2343,19 +1820,21 @@ impl SelectionSet { let mut updated_selections = MultiIndexMap::new(); updated_selections.extend( self.selections - .iter() + .values() .take(index) - .map(|(k, v)| (k.clone(), v.clone())), + .map(|v| (v.key().to_owned_key(), v.clone())), ); let mut update_new_selection = |selection| match selection { SelectionMapperReturn::None => {} // Removed; Skip it. SelectionMapperReturn::Selection(new_selection) => { - updated_selections.insert(new_selection.key(), new_selection) - } - SelectionMapperReturn::SelectionList(new_selections) => { - updated_selections.extend(new_selections.into_iter().map(|s| (s.key(), s))) + updated_selections.insert(new_selection.key().to_owned_key(), new_selection) } + SelectionMapperReturn::SelectionList(new_selections) => updated_selections.extend( + new_selections + .into_iter() + .map(|s| (s.key().to_owned_key(), s)), + ), }; // Now update the rest of the selections using the `mapper` function. @@ -2458,11 +1937,11 @@ impl SelectionSet { fn has_top_level_typename_field(&self) -> bool { const TYPENAME_KEY: SelectionKey = SelectionKey::Field { - response_name: TYPENAME_FIELD, - directives: DirectiveList::new(), + response_name: &TYPENAME_FIELD, + directives: &DirectiveList::new(), }; - self.selections.contains_key(&TYPENAME_KEY) + self.selections.contains_key(TYPENAME_KEY) } /// Adds a path, and optional some selections following that path, to this selection map. @@ -2671,7 +2150,7 @@ impl SelectionSet { selection_map.insert(selection.clone()); } else { let updated_field = match alias { - Some(alias) => field.with_updated_alias(alias.alias.clone()), + Some(alias) => field.field.with_updated_alias(alias.alias.clone()), None => field.field.clone(), }; selection_map @@ -2713,7 +2192,7 @@ impl SelectionSet { fn fields_in_set(&self) -> Vec { let mut fields = Vec::new(); - for (_key, selection) in self.selections.iter() { + for selection in self.selections.values() { match selection { Selection::Field(field) => fields.push(CollectedFieldInSet { path: Vec::new(), @@ -2831,29 +2310,29 @@ impl SelectionSet { } impl IntoIterator for SelectionSet { - type Item = as IntoIterator>::Item; - type IntoIter = as IntoIterator>::IntoIter; + type Item = Selection; + type IntoIter = selection_map::IntoValues; fn into_iter(self) -> Self::IntoIter { - Arc::unwrap_or_clone(self.selections).into_iter() + Arc::unwrap_or_clone(self.selections).into_values() } } impl<'a> IntoIterator for &'a SelectionSet { - type Item = <&'a IndexMap as IntoIterator>::Item; - type IntoIter = <&'a IndexMap as IntoIterator>::IntoIter; + type Item = &'a Selection; + type IntoIter = selection_map::Values<'a>; fn into_iter(self) -> Self::IntoIter { - self.selections.as_ref().into_iter() + self.selections.values() } } pub(crate) struct FieldSelectionsIter<'sel> { - stack: Vec>, + stack: Vec>, } impl<'sel> FieldSelectionsIter<'sel> { - fn new(iter: indexmap::map::Values<'sel, SelectionKey, Selection>) -> Self { + fn new(iter: selection_map::Values<'sel>) -> Self { Self { stack: vec![iter] } } } @@ -2936,7 +2415,7 @@ fn compute_aliases_for_non_merging_fields( let response_name = field.field.response_name(); let field_type = &field.field.field_position.get(field_schema)?.ty; - match seen_response_names.get(&response_name) { + match seen_response_names.get(response_name) { Some(previous) => { if &previous.field_name == field_name && types_can_be_merged(&previous.field_type, field_type, schema.schema())? @@ -2967,7 +2446,7 @@ fn compute_aliases_for_non_merging_fields( selections: field.selection_set.clone(), }); seen_response_names.insert( - response_name, + response_name.clone(), SeenResponseName { field_name: previous.field_name.clone(), field_type: previous.field_type.clone(), @@ -2979,7 +2458,7 @@ fn compute_aliases_for_non_merging_fields( } } else { // We need to alias the new occurence. - let alias = gen_alias_name(&response_name, &seen_response_names); + let alias = gen_alias_name(response_name, &seen_response_names); // Given how we generate aliases, it's is very unlikely that the generated alias will conflict with any of the other response name // at the level, but it's theoretically possible. By adding the alias to the seen names, we ensure that in the remote change that @@ -3009,7 +2488,7 @@ fn compute_aliases_for_non_merging_fields( alias_collector.push(FieldToAlias { path, - response_name, + response_name: response_name.clone(), alias, }) } @@ -3030,7 +2509,7 @@ fn compute_aliases_for_non_merging_fields( None => None, }; seen_response_names.insert( - response_name, + response_name.clone(), SeenResponseName { field_name: field_name.clone(), field_type: field_type.clone(), @@ -3061,7 +2540,7 @@ fn gen_alias_name(base_name: &Name, unavailable_names: &IndexMap Self { + fn with_updated_element(&self, field: Field) -> Self { Self { - field: Field::new(element), - ..self.clone() + field, + selection_set: self.selection_set.clone(), } } @@ -3203,13 +2682,13 @@ impl InlineFragmentSelection { }; let new_selection_set = SelectionSet::from_selection_set(&inline_fragment.selection_set, fragments, schema)?; - let new_inline_fragment = InlineFragment::new(InlineFragmentData { + let new_inline_fragment = InlineFragment { schema: schema.clone(), parent_type_position: parent_type_position.clone(), type_condition_position, directives: inline_fragment.directives.clone().into(), selection_id: SelectionId::new(), - }); + }; Ok(InlineFragmentSelection::new( new_inline_fragment, new_selection_set, @@ -3242,7 +2721,7 @@ impl InlineFragmentSelection { // Note: We assume that fragment_spread_selection.spread.type_condition_position is the same as // fragment_spread_selection.selection_set.type_position. Ok(InlineFragmentSelection::new( - InlineFragment::new(InlineFragmentData { + InlineFragment { schema: fragment_spread_selection.spread.schema.clone(), parent_type_position, type_condition_position: Some( @@ -3253,7 +2732,7 @@ impl InlineFragmentSelection { ), directives: fragment_spread_selection.spread.directives.clone(), selection_id: SelectionId::new(), - }), + }, fragment_spread_selection .selection_set .expand_all_fragments()?, @@ -3267,14 +2746,14 @@ impl InlineFragmentSelection { selection_set: SelectionSet, directives: DirectiveList, ) -> Self { - let inline_fragment_data = InlineFragmentData { + let inline_fragment_data = InlineFragment { schema: selection_set.schema.clone(), parent_type_position, type_condition_position: selection_set.type_position.clone().into(), directives, selection_id: SelectionId::new(), }; - InlineFragmentSelection::new(InlineFragment::new(inline_fragment_data), selection_set) + InlineFragmentSelection::new(inline_fragment_data, selection_set) } pub(crate) fn casted_type(&self) -> &CompositeTypeDefinitionPosition { @@ -3474,8 +2953,7 @@ impl NamedFragments { } if selection_set.selections.len() == 1 { // true if NOT field selection OR non-leaf field - return if let Some((_, Selection::Field(field_selection))) = - selection_set.selections.first() + return if let Some(Selection::Field(field_selection)) = selection_set.selections.first() { field_selection.selection_set.is_some() } else { @@ -3518,26 +2996,17 @@ impl DeferNormalizer { assigned_labels: IndexSet::default(), conditions: IndexMap::default(), }; - let mut stack = selection_set - .into_iter() - .map(|(_, sel)| sel) - .collect::>(); + let mut stack = selection_set.into_iter().collect::>(); while let Some(selection) = stack.pop() { if let Selection::InlineFragment(inline) = selection { - if let Some(args) = inline.inline_fragment.data().defer_directive_arguments()? { + if let Some(args) = inline.inline_fragment.defer_directive_arguments()? { let DeferDirectiveArguments { label, if_: _ } = args; if let Some(label) = label { digest.used_labels.insert(label); } } } - stack.extend( - selection - .selection_set() - .into_iter() - .flatten() - .map(|(_, sel)| sel), - ); + stack.extend(selection.selection_set().into_iter().flatten()); } Ok(digest) } @@ -3644,9 +3113,9 @@ impl FragmentSpread { } fn without_defer(&self, filter: DeferFilter<'_>) -> Result { - let mut data = self.data().clone(); - filter.remove_defer(&mut data.directives, data.schema.schema()); - Ok(Self::new(data)) + let mut without_defer = self.clone(); + filter.remove_defer(&mut without_defer.directives, without_defer.schema.schema()); + Ok(without_defer) } } @@ -3663,9 +3132,9 @@ impl InlineFragment { } fn without_defer(&self, filter: DeferFilter<'_>) -> Result { - let mut data = self.data().clone(); - filter.remove_defer(&mut data.directives, data.schema.schema()); - Ok(Self::new(data)) + let mut without_defer = self.clone(); + filter.remove_defer(&mut without_defer.directives, without_defer.schema.schema()); + Ok(without_defer) } } @@ -3844,8 +3313,8 @@ impl SelectionSet { selections, } = self; Arc::unwrap_or_clone(selections) - .into_iter() - .map(|(_, sel)| sel.normalize_defer(normalizer)) + .into_values() + .map(|sel| sel.normalize_defer(normalizer)) .try_collect() .map(|selections| Self { schema, diff --git a/apollo-federation/src/operation/optimize.rs b/apollo-federation/src/operation/optimize.rs index bde0b6dfa9..c7e54b23f7 100644 --- a/apollo-federation/src/operation/optimize.rs +++ b/apollo-federation/src/operation/optimize.rs @@ -51,6 +51,7 @@ use super::Field; use super::FieldSelection; use super::Fragment; use super::FragmentSpreadSelection; +use super::HasSelectionKey; use super::InlineFragmentSelection; use super::NamedFragments; use super::Operation; @@ -60,7 +61,6 @@ use super::SelectionOrSet; use super::SelectionSet; use crate::error::FederationError; use crate::operation::FragmentSpread; -use crate::operation::FragmentSpreadData; use crate::operation::SelectionValue; use crate::schema::position::CompositeTypeDefinitionPosition; @@ -228,10 +228,7 @@ impl Selection { let diff = self_sub_selection.minus(other_sub_selection)?; if !diff.is_empty() { return self - .with_updated_selections( - self_sub_selection.type_position.clone(), - diff.into_iter().map(|(_, v)| v), - ) + .with_updated_selections(self_sub_selection.type_position.clone(), diff) .map(Some); } } @@ -251,10 +248,7 @@ impl Selection { return Ok(None); } else { return self - .with_updated_selections( - self_sub_selection.type_position.clone(), - common.into_iter().map(|(_, v)| v), - ) + .with_updated_selections(self_sub_selection.type_position.clone(), common) .map(Some); } } @@ -268,9 +262,9 @@ impl SelectionSet { pub(crate) fn minus(&self, other: &SelectionSet) -> Result { let iter = self .selections - .iter() - .map(|(k, v)| { - if let Some(other_v) = other.selections.get(k) { + .values() + .map(|v| { + if let Some(other_v) = other.selections.get(v.key()) { v.minus(other_v) } else { Ok(Some(v.clone())) @@ -297,9 +291,9 @@ impl SelectionSet { let iter = self .selections - .iter() - .map(|(k, v)| { - if let Some(other_v) = other.selections.get(k) { + .values() + .map(|v| { + if let Some(other_v) = other.selections.get(v.key()) { v.intersection(other_v) } else { Ok(None) @@ -413,7 +407,7 @@ impl FieldsConflictValidator { for selection_set in level { for field_selection in selection_set.field_selections() { let response_name = field_selection.field.response_name(); - let at_response_name = at_level.entry(response_name).or_default(); + let at_response_name = at_level.entry(response_name.clone()).or_default(); let entry = at_response_name .entry(field_selection.field.clone()) .or_default(); @@ -443,7 +437,7 @@ impl FieldsConflictValidator { fn for_field<'v>(&'v self, field: &Field) -> impl Iterator> + 'v { self.by_response_name - .get(&field.response_name()) + .get(field.response_name()) .into_iter() .flat_map(|by_response_name| by_response_name.values()) .flatten() @@ -682,10 +676,11 @@ impl FragmentRestrictionAtType { // Using `F` in those cases is, while not 100% incorrect, at least not productive, and so we // skip it that case. This is essentially an optimization. fn is_useless(&self) -> bool { - match self.selections.selections.as_slice().split_first() { - None => true, - Some((first, rest)) => rest.is_empty() && first.0.is_typename_field(), - } + let mut iter = self.selections.iter(); + let Some(first) = iter.next() else { + return true; + }; + iter.next().is_none() && first.is_typename_field() } } @@ -751,7 +746,7 @@ impl Fragment { return false; } - self.selection_set.selections.iter().any(|(_, selection)| { + self.selection_set.selections.values().any(|selection| { matches!( selection, Selection::FragmentSpread(fragment) if fragment.spread.fragment_name == *other_fragment_name @@ -1384,7 +1379,7 @@ impl InlineFragmentSelection { // case they should be kept on the spread. // PORT_NOTE: We are assuming directives on fragment definitions are // carried over to their spread sites as JS version does, which - // is handled differently in Rust version (see `FragmentSpreadData`). + // is handled differently in Rust version (see `FragmentSpread`). let directives: executable::DirectiveList = self .inline_fragment .directives @@ -1662,7 +1657,7 @@ impl FragmentGenerator { selection_set.type_position.clone(), ); - for (_key, selection) in Arc::make_mut(&mut selection_set.selections).iter_mut() { + for selection in Arc::make_mut(&mut selection_set.selections).values_mut() { match selection { SelectionValue::Field(mut field) => { if let Some(selection_set) = field.get_selection_set_mut() { @@ -1751,14 +1746,14 @@ impl FragmentGenerator { }; new_selection_set.add_local_selection(&Selection::from( FragmentSpreadSelection { - spread: FragmentSpread::new(FragmentSpreadData { + spread: FragmentSpread { schema: selection_set.schema.clone(), fragment_name: existing.name.clone(), type_condition_position: existing.type_condition_position.clone(), directives: skip_include.into(), fragment_directives: existing.directives.clone(), selection_id: crate::operation::SelectionId::new(), - }), + }, selection_set: existing.selection_set.clone(), }, ))?; @@ -3507,14 +3502,14 @@ mod tests { match path.split_first() { None => { // Base case - Arc::make_mut(&mut ss.selections).clear(); + ss.selections = Default::default(); Ok(()) } Some((first, rest)) => { - let result = Arc::make_mut(&mut ss.selections).get_mut(&SelectionKey::Field { - response_name: (*first).clone(), - directives: Default::default(), + let result = Arc::make_mut(&mut ss.selections).get_mut(SelectionKey::Field { + response_name: first, + directives: &Default::default(), }); let Some(mut value) = result else { return Err(FederationError::internal("No matching field found")); diff --git a/apollo-federation/src/operation/rebase.rs b/apollo-federation/src/operation/rebase.rs index 5e2d29c75d..ffc16d1b01 100644 --- a/apollo-federation/src/operation/rebase.rs +++ b/apollo-federation/src/operation/rebase.rs @@ -11,10 +11,8 @@ use super::Field; use super::FieldSelection; use super::Fragment; use super::FragmentSpread; -use super::FragmentSpreadData; use super::FragmentSpreadSelection; use super::InlineFragment; -use super::InlineFragmentData; use super::InlineFragmentSelection; use super::NamedFragments; use super::OperationElement; @@ -191,28 +189,28 @@ impl Field { } .into()) } else { - let mut updated_field_data = self.data().clone(); - updated_field_data.schema = schema.clone(); - updated_field_data.field_position = parent_type.introspection_typename_field(); - Ok(Field::new(updated_field_data)) + let mut updated_field = self.clone(); + updated_field.schema = schema.clone(); + updated_field.field_position = parent_type.introspection_typename_field(); + Ok(updated_field) }; } let field_from_parent = parent_type.field(self.name().clone())?; - return if field_from_parent.try_get(schema.schema()).is_some() + if field_from_parent.try_get(schema.schema()).is_some() && self.can_rebase_on(parent_type)? { - let mut updated_field_data = self.data().clone(); - updated_field_data.schema = schema.clone(); - updated_field_data.field_position = field_from_parent; - Ok(Field::new(updated_field_data)) + let mut updated_field = self.clone(); + updated_field.schema = schema.clone(); + updated_field.field_position = field_from_parent; + Ok(updated_field) } else { Err(RebaseError::CannotRebase { field_position: self.field_position.clone(), parent_type: parent_type.clone(), } .into()) - }; + } } /// Verifies whether given field can be rebase on following parent type. @@ -390,10 +388,10 @@ impl FragmentSpread { &named_fragment.type_condition_position, &self.schema, ) { - Ok(FragmentSpread::new(FragmentSpreadData::from_fragment( + Ok(FragmentSpread::from_fragment( named_fragment, &self.directives, - ))) + )) } else { Err(RebaseError::NonIntersectingCondition { type_condition: named_fragment.type_condition_position.clone().into(), @@ -474,23 +472,20 @@ impl FragmentSpreadSelection { Err(RebaseError::EmptySelectionSet.into()) } else { Ok(InlineFragmentSelection::new( - InlineFragment::new(InlineFragmentData { + InlineFragment { schema: schema.clone(), parent_type_position: parent_type.clone(), type_condition_position: None, directives: Default::default(), selection_id: SelectionId::new(), - }), + }, expanded_selection_set, ) .into()) }; } - let spread = FragmentSpread::new(FragmentSpreadData::from_fragment( - named_fragment, - &self.spread.directives, - )); + let spread = FragmentSpread::from_fragment(named_fragment, &self.spread.directives); Ok(FragmentSpreadSelection { spread, selection_set: named_fragment.selection_set.clone(), @@ -508,7 +503,7 @@ impl FragmentSpreadSelection { } } -impl InlineFragmentData { +impl InlineFragment { fn casted_type_if_add_to( &self, parent_type: &CompositeTypeDefinitionPosition, @@ -517,33 +512,18 @@ impl InlineFragmentData { if self.schema == *schema && self.parent_type_position == *parent_type { return Some(self.casted_type()); } - match self.can_rebase_on(parent_type, schema) { - (false, _) => None, - (true, None) => Some(parent_type.clone()), - (true, Some(ty)) => Some(ty), - } - } - - fn can_rebase_on( - &self, - parent_type: &CompositeTypeDefinitionPosition, - schema: &ValidFederationSchema, - ) -> (bool, Option) { let Some(ty) = self.type_condition_position.as_ref() else { - return (true, None); + return Some(parent_type.clone()); }; - match schema + + let rebased_type = schema .get_type(ty.type_name().clone()) .ok() - .and_then(|ty| CompositeTypeDefinitionPosition::try_from(ty).ok()) - { - Some(ty) if runtime_types_intersect(parent_type, &ty, schema) => (true, Some(ty)), - _ => (false, None), - } + .and_then(|ty| CompositeTypeDefinitionPosition::try_from(ty).ok())?; + + runtime_types_intersect(parent_type, &rebased_type, schema).then_some(rebased_type) } -} -impl InlineFragment { pub(crate) fn rebase_on( &self, parent_type: &CompositeTypeDefinitionPosition, @@ -566,11 +546,11 @@ impl InlineFragment { } .into()) } else { - let mut rebased_fragment_data = self.data().clone(); - rebased_fragment_data.parent_type_position = parent_type.clone(); - rebased_fragment_data.type_condition_position = rebased_condition; - rebased_fragment_data.schema = schema.clone(); - Ok(InlineFragment::new(rebased_fragment_data)) + let mut rebased_fragment = self.clone(); + rebased_fragment.parent_type_position = parent_type.clone(); + rebased_fragment.type_condition_position = rebased_condition; + rebased_fragment.schema = schema.clone(); + Ok(rebased_fragment) } } @@ -710,8 +690,8 @@ impl SelectionSet { ) -> Result { let rebased_results = self .selections - .iter() - .map(|(_, selection)| { + .values() + .map(|selection| { selection.rebase_inner( parent_type, named_fragments, diff --git a/apollo-federation/src/operation/selection_map.rs b/apollo-federation/src/operation/selection_map.rs new file mode 100644 index 0000000000..19857ba274 --- /dev/null +++ b/apollo-federation/src/operation/selection_map.rs @@ -0,0 +1,647 @@ +use std::borrow::Cow; +use std::hash::BuildHasher; +use std::sync::Arc; + +use apollo_compiler::Name; +use hashbrown::DefaultHashBuilder; +use hashbrown::HashTable; +use serde::ser::SerializeSeq; +use serde::Serialize; + +use crate::error::FederationError; +use crate::operation::field_selection::FieldSelection; +use crate::operation::fragment_spread_selection::FragmentSpreadSelection; +use crate::operation::inline_fragment_selection::InlineFragmentSelection; +use crate::operation::DirectiveList; +use crate::operation::Selection; +use crate::operation::SelectionId; +use crate::operation::SelectionSet; +use crate::operation::SiblingTypename; + +/// A selection "key" (unrelated to the federation `@key` directive) is an identifier of a selection +/// (field, inline fragment, or fragment spread) that is used to determine whether two selections +/// can be merged. +/// +/// In order to merge two selections they need to +/// * reference the same field/inline fragment +/// * specify the same directives +/// * directives have to be applied in the same order +/// * directive arguments order does not matter (they get automatically sorted by their names). +/// * selection cannot specify @defer directive +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize)] +pub(crate) enum SelectionKey<'a> { + Field { + /// The field alias (if specified) or field name in the resulting selection set. + response_name: &'a Name, + /// directives applied on the field + #[serde(serialize_with = "crate::display_helpers::serialize_as_string")] + directives: &'a DirectiveList, + }, + FragmentSpread { + /// The name of the fragment. + fragment_name: &'a Name, + /// Directives applied on the fragment spread (does not contain @defer). + #[serde(serialize_with = "crate::display_helpers::serialize_as_string")] + directives: &'a DirectiveList, + }, + InlineFragment { + /// The optional type condition of the fragment. + type_condition: Option<&'a Name>, + /// Directives applied on the fragment spread (does not contain @defer). + #[serde(serialize_with = "crate::display_helpers::serialize_as_string")] + directives: &'a DirectiveList, + }, + Defer { + /// Unique selection ID used to distinguish deferred fragment spreads that cannot be merged. + #[cfg_attr(not(feature = "snapshot_tracing"), serde(skip))] + deferred_id: SelectionId, + }, +} + +impl SelectionKey<'_> { + /// Get an owned structure representing the selection key, for use in map keys + /// that are not a plain selection map. + pub(crate) fn to_owned_key(self) -> OwnedSelectionKey { + match self { + Self::Field { + response_name, + directives, + } => OwnedSelectionKey::Field { + response_name: response_name.clone(), + directives: directives.clone(), + }, + Self::FragmentSpread { + fragment_name, + directives, + } => OwnedSelectionKey::FragmentSpread { + fragment_name: fragment_name.clone(), + directives: directives.clone(), + }, + Self::InlineFragment { + type_condition, + directives, + } => OwnedSelectionKey::InlineFragment { + type_condition: type_condition.cloned(), + directives: directives.clone(), + }, + Self::Defer { deferred_id } => OwnedSelectionKey::Defer { deferred_id }, + } + } +} + +/// An owned structure representing the selection key, for use in map keys +/// that are not a plain selection map. +#[derive(Debug, Clone, Hash, PartialEq, Eq)] +pub(crate) enum OwnedSelectionKey { + Field { + response_name: Name, + directives: DirectiveList, + }, + FragmentSpread { + fragment_name: Name, + directives: DirectiveList, + }, + InlineFragment { + type_condition: Option, + directives: DirectiveList, + }, + Defer { + deferred_id: SelectionId, + }, +} + +impl OwnedSelectionKey { + /// Get a plain, borrowed selection key, that can be used for indexing into a selection map. + pub(crate) fn as_borrowed_key(&self) -> SelectionKey<'_> { + match self { + OwnedSelectionKey::Field { + response_name, + directives, + } => SelectionKey::Field { + response_name, + directives, + }, + OwnedSelectionKey::FragmentSpread { + fragment_name, + directives, + } => SelectionKey::FragmentSpread { + fragment_name, + directives, + }, + OwnedSelectionKey::InlineFragment { + type_condition, + directives, + } => SelectionKey::InlineFragment { + type_condition: type_condition.as_ref(), + directives, + }, + OwnedSelectionKey::Defer { deferred_id } => SelectionKey::Defer { + deferred_id: *deferred_id, + }, + } + } +} + +impl<'a> SelectionKey<'a> { + /// Create a selection key for a specific field name. + /// + /// This is available for tests only as selection keys should not normally be created outside of + /// `HasSelectionKey::key`. + #[cfg(test)] + pub(crate) fn field_name(name: &'a Name) -> Self { + static EMPTY_LIST: DirectiveList = DirectiveList::new(); + SelectionKey::Field { + response_name: name, + directives: &EMPTY_LIST, + } + } +} + +pub(crate) trait HasSelectionKey { + fn key(&self) -> SelectionKey<'_>; +} + +#[derive(Clone)] +struct Bucket { + index: usize, + hash: u64, +} + +/// A selection map is the underlying representation of a selection set. It contains an ordered +/// list of selections with unique selection keys. Selections with the same key should be merged +/// together by the user of this structure: the selection map API itself will overwrite selections +/// with the same key. +/// +/// Once a selection is in the selection map, it must not be modified in a way that changes the +/// selection key. Therefore, the selection map only hands out mutable access through the +/// SelectionValue types, which expose the parts of selections that are safe to modify. +#[derive(Clone)] +pub(crate) struct SelectionMap { + hash_builder: DefaultHashBuilder, + table: HashTable, + selections: Vec, +} + +impl std::fmt::Debug for SelectionMap { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_set().entries(self.values()).finish() + } +} + +impl PartialEq for SelectionMap { + /// Compare two selection maps. This is order independent. + fn eq(&self, other: &Self) -> bool { + self.len() == other.len() + && self + .values() + .all(|left| other.get(left.key()).is_some_and(|right| left == right)) + } +} + +impl Eq for SelectionMap {} + +impl Serialize for SelectionMap { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut seq = serializer.serialize_seq(Some(self.len()))?; + for value in self.values() { + seq.serialize_element(value)?; + } + seq.end() + } +} + +impl Default for SelectionMap { + fn default() -> Self { + Self::new() + } +} + +pub(crate) type Values<'a> = std::slice::Iter<'a, Selection>; +pub(crate) type ValuesMut<'a> = + std::iter::Map, fn(&'a mut Selection) -> SelectionValue<'a>>; +pub(crate) type IntoValues = std::vec::IntoIter; + +/// Return an equality function taking an index into `selections` and returning if the index +/// matches the given key. +/// +/// The returned function panics if the index is out of bounds. +fn key_eq<'a>(selections: &'a [Selection], key: SelectionKey<'a>) -> impl Fn(&Bucket) -> bool + 'a { + move |bucket| selections[bucket.index].key() == key +} + +impl SelectionMap { + /// Create an empty selection map. + pub(crate) fn new() -> Self { + SelectionMap { + hash_builder: Default::default(), + table: HashTable::new(), + selections: Vec::new(), + } + } + + /// Returns the number of selections in the map. + pub(crate) fn len(&self) -> usize { + self.selections.len() + } + + /// Returns true if there are no selections in the map. + pub(crate) fn is_empty(&self) -> bool { + self.selections.is_empty() + } + + /// Returns the first selection in the map, or None if the map is empty. + pub(crate) fn first(&self) -> Option<&Selection> { + self.selections.first() + } + + /// Computes the hash of a selection key. + fn hash(&self, key: SelectionKey<'_>) -> u64 { + self.hash_builder.hash_one(key) + } + + /// Returns true if the given key exists in the map. + pub(crate) fn contains_key(&self, key: SelectionKey<'_>) -> bool { + let hash = self.hash(key); + self.table + .find(hash, key_eq(&self.selections, key)) + .is_some() + } + + /// Returns true if the given key exists in the map. + pub(crate) fn get(&self, key: SelectionKey<'_>) -> Option<&Selection> { + let hash = self.hash(key); + let bucket = self.table.find(hash, key_eq(&self.selections, key))?; + Some(&self.selections[bucket.index]) + } + + pub(crate) fn get_mut(&mut self, key: SelectionKey<'_>) -> Option> { + let hash = self.hash(key); + let bucket = self.table.find_mut(hash, key_eq(&self.selections, key))?; + Some(SelectionValue::new(&mut self.selections[bucket.index])) + } + + /// Insert a selection into the map. + fn raw_insert(&mut self, hash: u64, value: Selection) -> &mut Selection { + let index = self.selections.len(); + + self.table + .insert_unique(hash, Bucket { index, hash }, |existing| existing.hash); + + self.selections.push(value); + &mut self.selections[index] + } + + /// Resets and rebuilds the hash table. + /// + /// Preconditions: + /// - The table must have enough capacity for `self.selections.len()` elements. + fn rebuild_table_no_grow(&mut self) { + assert!(self.table.capacity() >= self.selections.len()); + self.table.clear(); + for (index, selection) in self.selections.iter().enumerate() { + let hash = self.hash(selection.key()); + self.table + .insert_unique(hash, Bucket { index, hash }, |existing| existing.hash); + } + } + + /// Decrements all the indices in the table starting at `pivot`. + fn decrement_table(&mut self, pivot: usize) { + for bucket in self.table.iter_mut() { + if bucket.index >= pivot { + bucket.index -= 1; + } + } + } + + pub(crate) fn insert(&mut self, value: Selection) { + let hash = self.hash(value.key()); + self.raw_insert(hash, value); + } + + /// Remove a selection from the map. Returns the selection and its numeric index. + pub(crate) fn remove(&mut self, key: SelectionKey<'_>) -> Option<(usize, Selection)> { + let hash = self.hash(key); + let entry = self + .table + .find_entry(hash, key_eq(&self.selections, key)) + .ok()?; + let (bucket, _) = entry.remove(); + let selection = self.selections.remove(bucket.index); + self.decrement_table(bucket.index); + Some((bucket.index, selection)) + } + + pub(crate) fn retain( + &mut self, + mut predicate: impl FnMut(SelectionKey<'_>, &Selection) -> bool, + ) { + self.selections.retain(|selection| { + let key = selection.key(); + predicate(key, selection) + }); + if self.selections.len() < self.table.len() { + // In theory, we could track which keys were removed, and adjust the indices based on + // that, but it's very tricky and it might not even be faster than just resetting the + // whole map. + self.rebuild_table_no_grow(); + } + assert!(self.selections.len() == self.table.len()); + } + + /// Iterate over all selections. + pub(crate) fn values(&self) -> Values<'_> { + self.selections.iter() + } + + /// Iterate over all selections. + pub(crate) fn values_mut(&mut self) -> ValuesMut<'_> { + self.selections.iter_mut().map(SelectionValue::new) + } + + /// Iterate over all selections. + pub(crate) fn into_values(self) -> IntoValues { + self.selections.into_iter() + } + + /// Provides mutable access to a selection key. A new selection can be inserted or an existing + /// selection modified. + pub(super) fn entry<'a>(&'a mut self, key: SelectionKey<'a>) -> Entry<'a> { + let hash = self.hash(key); + let slot = self.table.find_entry(hash, key_eq(&self.selections, key)); + match slot { + Ok(occupied) => { + let index = occupied.get().index; + let selection = &mut self.selections[index]; + Entry::Occupied(OccupiedEntry(selection)) + } + // We're not using `hashbrown`'s VacantEntry API here, because we have some custom + // insertion logic, it's easier to use `SelectionMap::raw_insert` to implement + // `VacantEntry::or_insert`. + Err(_) => Entry::Vacant(VacantEntry { + map: self, + hash, + key, + }), + } + } + + /// Add selections from another selection map to this one. If there are key collisions, the + /// selections are *overwritten*. + pub(crate) fn extend(&mut self, other: SelectionMap) { + for selection in other.into_values() { + self.insert(selection); + } + } + + /// Add selections from another selection map to this one. If there are key collisions, the + /// selections are *overwritten*. + pub(crate) fn extend_ref(&mut self, other: &SelectionMap) { + for selection in other.values() { + self.insert(selection.clone()); + } + } + + /// Returns the selection set resulting from "recursively" filtering any selection + /// that does not match the provided predicate. + /// This method calls `predicate` on every selection of the selection set, + /// not just top-level ones, and apply a "depth-first" strategy: + /// when the predicate is called on a given selection it is guaranteed that + /// filtering has happened on all the selections of its sub-selection. + pub(crate) fn filter_recursive_depth_first( + &self, + predicate: &mut dyn FnMut(&Selection) -> Result, + ) -> Result, FederationError> { + fn recur_sub_selections<'sel>( + selection: &'sel Selection, + predicate: &mut dyn FnMut(&Selection) -> Result, + ) -> Result, FederationError> { + Ok(match selection { + Selection::Field(field) => { + if let Some(sub_selections) = &field.selection_set { + match sub_selections.filter_recursive_depth_first(predicate)? { + Cow::Borrowed(_) => Cow::Borrowed(selection), + Cow::Owned(new) => { + Cow::Owned(Selection::from_field(field.field.clone(), Some(new))) + } + } + } else { + Cow::Borrowed(selection) + } + } + Selection::InlineFragment(fragment) => match fragment + .selection_set + .filter_recursive_depth_first(predicate)? + { + Cow::Borrowed(_) => Cow::Borrowed(selection), + Cow::Owned(selection_set) => Cow::Owned(Selection::InlineFragment(Arc::new( + InlineFragmentSelection::new( + fragment.inline_fragment.clone(), + selection_set, + ), + ))), + }, + Selection::FragmentSpread(_) => { + return Err(FederationError::internal("unexpected fragment spread")) + } + }) + } + let mut iter = self.values(); + let mut enumerated = (&mut iter).enumerate(); + let mut new_map: Self; + loop { + let Some((index, selection)) = enumerated.next() else { + return Ok(Cow::Borrowed(self)); + }; + let filtered = recur_sub_selections(selection, predicate)?; + let keep = predicate(&filtered)?; + if keep && matches!(filtered, Cow::Borrowed(_)) { + // Nothing changed so far, continue without cloning + continue; + } + + // Clone the map so far + new_map = self.selections[..index].iter().cloned().collect(); + + if keep { + new_map.insert(filtered.into_owned()); + } + break; + } + for selection in iter { + let filtered = recur_sub_selections(selection, predicate)?; + if predicate(&filtered)? { + new_map.insert(filtered.into_owned()); + } + } + Ok(Cow::Owned(new_map)) + } +} + +impl FromIterator for SelectionMap +where + A: Into, +{ + /// Create a selection map from an iterator of selections. On key collisions, *only the later + /// selection is used*. + fn from_iter>(iter: T) -> Self { + let mut map = Self::new(); + for selection in iter { + map.insert(selection.into()); + } + map + } +} + +/// A mutable reference to a `Selection` value in a `SelectionMap`, which +/// also disallows changing key-related data (to maintain the invariant that a value's key is +/// the same as it's map entry's key). +#[derive(Debug)] +pub(crate) enum SelectionValue<'a> { + Field(FieldSelectionValue<'a>), + FragmentSpread(FragmentSpreadSelectionValue<'a>), + InlineFragment(InlineFragmentSelectionValue<'a>), +} + +impl<'a> SelectionValue<'a> { + fn new(selection: &'a mut Selection) -> Self { + match selection { + Selection::Field(field_selection) => { + SelectionValue::Field(FieldSelectionValue::new(field_selection)) + } + Selection::FragmentSpread(fragment_spread_selection) => SelectionValue::FragmentSpread( + FragmentSpreadSelectionValue::new(fragment_spread_selection), + ), + Selection::InlineFragment(inline_fragment_selection) => SelectionValue::InlineFragment( + InlineFragmentSelectionValue::new(inline_fragment_selection), + ), + } + } + + pub(super) fn key(&self) -> SelectionKey<'_> { + match self { + Self::Field(field) => field.get().key(), + Self::FragmentSpread(frag) => frag.get().key(), + Self::InlineFragment(frag) => frag.get().key(), + } + } + + // This is used in operation::optimize tests + #[cfg(test)] + pub(super) fn get_selection_set_mut(&mut self) -> Option<&mut SelectionSet> { + match self { + SelectionValue::Field(field) => field.get_selection_set_mut(), + SelectionValue::FragmentSpread(frag) => Some(frag.get_selection_set_mut()), + SelectionValue::InlineFragment(frag) => Some(frag.get_selection_set_mut()), + } + } +} + +#[derive(Debug)] +pub(crate) struct FieldSelectionValue<'a>(&'a mut Arc); + +impl<'a> FieldSelectionValue<'a> { + pub(crate) fn new(field_selection: &'a mut Arc) -> Self { + Self(field_selection) + } + + pub(crate) fn get(&self) -> &Arc { + self.0 + } + + pub(crate) fn get_sibling_typename_mut(&mut self) -> &mut Option { + Arc::make_mut(self.0).field.sibling_typename_mut() + } + + pub(crate) fn get_selection_set_mut(&mut self) -> Option<&mut SelectionSet> { + Arc::make_mut(self.0).selection_set.as_mut() + } +} + +#[derive(Debug)] +pub(crate) struct FragmentSpreadSelectionValue<'a>(&'a mut Arc); + +impl<'a> FragmentSpreadSelectionValue<'a> { + pub(crate) fn new(fragment_spread_selection: &'a mut Arc) -> Self { + Self(fragment_spread_selection) + } + + pub(crate) fn get(&self) -> &Arc { + self.0 + } + + #[cfg(test)] + pub(crate) fn get_selection_set_mut(&mut self) -> &mut SelectionSet { + &mut Arc::make_mut(self.0).selection_set + } +} + +#[derive(Debug)] +pub(crate) struct InlineFragmentSelectionValue<'a>(&'a mut Arc); + +impl<'a> InlineFragmentSelectionValue<'a> { + pub(crate) fn new(inline_fragment_selection: &'a mut Arc) -> Self { + Self(inline_fragment_selection) + } + + pub(crate) fn get(&self) -> &Arc { + self.0 + } + + pub(crate) fn get_selection_set_mut(&mut self) -> &mut SelectionSet { + &mut Arc::make_mut(self.0).selection_set + } +} + +pub(crate) enum Entry<'a> { + Occupied(OccupiedEntry<'a>), + Vacant(VacantEntry<'a>), +} + +impl<'a> Entry<'a> { + pub(crate) fn or_insert( + self, + produce: impl FnOnce() -> Result, + ) -> Result, FederationError> { + match self { + Self::Occupied(entry) => Ok(entry.into_mut()), + Self::Vacant(entry) => entry.insert(produce()?), + } + } +} + +pub(crate) struct OccupiedEntry<'a>(&'a mut Selection); + +impl<'a> OccupiedEntry<'a> { + pub(crate) fn get(&self) -> &Selection { + self.0 + } + + pub(crate) fn into_mut(self) -> SelectionValue<'a> { + SelectionValue::new(self.0) + } +} + +pub(crate) struct VacantEntry<'a> { + map: &'a mut SelectionMap, + hash: u64, + key: SelectionKey<'a>, +} + +impl<'a> VacantEntry<'a> { + pub(crate) fn key(&self) -> SelectionKey<'a> { + self.key + } + + pub(crate) fn insert(self, value: Selection) -> Result, FederationError> { + if self.key() != value.key() { + return Err(FederationError::internal(format!( + "Key mismatch when inserting selection {value} into vacant entry " + ))); + }; + Ok(SelectionValue::new(self.map.raw_insert(self.hash, value))) + } +} diff --git a/apollo-federation/src/operation/simplify.rs b/apollo-federation/src/operation/simplify.rs index a436c9f380..29d4c55d9f 100644 --- a/apollo-federation/src/operation/simplify.rs +++ b/apollo-federation/src/operation/simplify.rs @@ -6,7 +6,6 @@ use apollo_compiler::name; use super::runtime_types_intersect; use super::DirectiveList; use super::Field; -use super::FieldData; use super::FieldSelection; use super::FragmentSpreadSelection; use super::InlineFragmentSelection; @@ -62,7 +61,7 @@ impl FieldSelection { let field_element = if self.field.schema() == schema && self.field.field_position == field_position { - self.field.data().clone() + self.field.clone() } else { self.field .with_updated_position(schema.clone(), field_position) @@ -89,7 +88,7 @@ impl FieldSelection { arguments: vec![(name!("if"), false).into()], }); let non_included_typename = Selection::from_field( - Field::new(FieldData { + Field { schema: schema.clone(), field_position: field_composite_type_position .introspection_typename_field(), @@ -97,7 +96,7 @@ impl FieldSelection { arguments: Default::default(), directives, sibling_typename: None, - }), + }, None, ); let mut typename_selection = SelectionMap::new(); @@ -229,14 +228,14 @@ impl InlineFragmentSelection { parent_type.introspection_typename_field() }; let typename_field_selection = Selection::from_field( - Field::new(FieldData { + Field { schema: schema.clone(), field_position: parent_typename_field, alias: None, arguments: Default::default(), directives, sibling_typename: None, - }), + }, None, ); @@ -260,7 +259,7 @@ impl InlineFragmentSelection { && this_condition.is_some_and(|c| c.is_abstract_type()) { let mut liftable_selections = SelectionMap::new(); - for (_, selection) in selection_set.selections.iter() { + for selection in selection_set.selections.values() { match selection { Selection::FragmentSpread(spread_selection) => { let type_condition = &spread_selection.spread.type_condition_position; @@ -296,7 +295,7 @@ impl InlineFragmentSelection { // Otherwise, if there are "liftable" selections, we must return a set comprised of those lifted selection, // and the current fragment _without_ those lifted selections. - if liftable_selections.len() > 0 { + if !liftable_selections.is_empty() { // Converting `... [on T] { }` into // `{ ... [on T] { } }`. // PORT_NOTE: It appears that this lifting could be repeatable (meaning lifted @@ -323,8 +322,8 @@ impl InlineFragmentSelection { // Since liftable_selections are changing their parent, we need to rebase them. liftable_selections = liftable_selections - .into_iter() - .map(|(_key, sel)| sel.rebase_on(parent_type, named_fragments, schema)) + .into_values() + .map(|sel| sel.rebase_on(parent_type, named_fragments, schema)) .collect::>()?; let mut final_selection_map = SelectionMap::new(); diff --git a/apollo-federation/src/operation/tests/mod.rs b/apollo-federation/src/operation/tests/mod.rs index 52eb810f7d..6988b8e659 100644 --- a/apollo-federation/src/operation/tests/mod.rs +++ b/apollo-federation/src/operation/tests/mod.rs @@ -4,6 +4,7 @@ use apollo_compiler::schema::Schema; use apollo_compiler::ExecutableDocument; use super::normalize_operation; +use super::Field; use super::Name; use super::NamedFragments; use super::Operation; @@ -1120,13 +1121,13 @@ fn converting_operation_types() { } fn contains_field(ss: &SelectionSet, field_name: Name) -> bool { - ss.selections.contains_key(&SelectionKey::Field { - response_name: field_name, - directives: Default::default(), + ss.selections.contains_key(SelectionKey::Field { + response_name: &field_name, + directives: &Default::default(), }) } -fn is_named_field(sk: &SelectionKey, name: Name) -> bool { +fn is_named_field(sk: SelectionKey, name: Name) -> bool { matches!(sk, SelectionKey::Field { response_name, directives: _ } if *response_name == name) @@ -1137,14 +1138,7 @@ fn get_value_at_path<'a>(ss: &'a SelectionSet, path: &[Name]) -> Option<&'a Sele // Error: empty path return None; }; - let result = ss.selections.get(&SelectionKey::Field { - response_name: (*first).clone(), - directives: Default::default(), - }); - let Some(value) = result else { - // Error: No matching field found. - return None; - }; + let value = ss.selections.get(SelectionKey::field_name(first))?; if rest.is_empty() { // Base case => We are done. Some(value) @@ -1305,14 +1299,14 @@ mod lazy_map_tests { // Remove `foo` let remove_foo = - filter_rec(&selection_set, &|s| !is_named_field(&s.key(), name!("foo"))).unwrap(); + filter_rec(&selection_set, &|s| !is_named_field(s.key(), name!("foo"))).unwrap(); assert!(contains_field(&remove_foo, name!("some_int"))); assert!(contains_field(&remove_foo, name!("foo2"))); assert!(!contains_field(&remove_foo, name!("foo"))); // Remove `bar` let remove_bar = - filter_rec(&selection_set, &|s| !is_named_field(&s.key(), name!("bar"))).unwrap(); + filter_rec(&selection_set, &|s| !is_named_field(s.key(), name!("bar"))).unwrap(); // "foo2" should be removed, since it has no sub-selections left. assert!(!contains_field(&remove_bar, name!("foo2"))); } @@ -1355,7 +1349,7 @@ mod lazy_map_tests { // Add __typename next to any "id" field. let result = - add_typename_if(&selection_set, &|s| is_named_field(&s.key(), name!("id"))).unwrap(); + add_typename_if(&selection_set, &|s| is_named_field(s.key(), name!("id"))).unwrap(); // The top level won't have __typename, since it doesn't have "id". assert!(!contains_field(&result, name!("__typename"))); @@ -1367,7 +1361,7 @@ mod lazy_map_tests { } fn field_element(schema: &ValidFederationSchema, object: Name, field: Name) -> OpPathElement { - OpPathElement::Field(super::Field::new(super::FieldData { + OpPathElement::Field(Field { schema: schema.clone(), field_position: ObjectTypeDefinitionPosition::new(object) .field(field) @@ -1376,7 +1370,7 @@ fn field_element(schema: &ValidFederationSchema, object: Name, field: Name) -> O arguments: Default::default(), directives: Default::default(), sibling_typename: None, - })) + }) } const ADD_AT_PATH_TEST_SCHEMA: &str = r#" @@ -1622,7 +1616,7 @@ fn used_variables() { let Selection::Field(subquery) = operation .selection_set .selections - .get(&SelectionKey::field_name("subquery")) + .get(SelectionKey::field_name(&name!("subquery"))) .unwrap() else { unreachable!(); diff --git a/apollo-federation/src/query_graph/graph_path.rs b/apollo-federation/src/query_graph/graph_path.rs index da06fffcdf..c01e1753dc 100644 --- a/apollo-federation/src/query_graph/graph_path.rs +++ b/apollo-federation/src/query_graph/graph_path.rs @@ -32,10 +32,8 @@ use crate::link::graphql_definition::OperationConditional; use crate::link::graphql_definition::OperationConditionalKind; use crate::operation::DirectiveList; use crate::operation::Field; -use crate::operation::FieldData; use crate::operation::HasSelectionKey; use crate::operation::InlineFragment; -use crate::operation::InlineFragmentData; use crate::operation::SelectionId; use crate::operation::SelectionKey; use crate::operation::SelectionSet; @@ -2509,14 +2507,14 @@ impl OpGraphPath { operation_field, edge_weight, self, ))); } - operation_field = Field::new(FieldData { + operation_field = Field { schema: self.graph.schema_by_source(&tail_weight.source)?.clone(), field_position: field_on_tail_type.into(), alias: operation_field.alias.clone(), arguments: operation_field.arguments.clone(), directives: operation_field.directives.clone(), sibling_typename: operation_field.sibling_typename.clone(), - }) + } } let field_path = self.add_field_edge( @@ -2702,19 +2700,15 @@ impl OpGraphPath { debug!("Handling implementation {implementation_type_pos}"); let span = debug_span!(" |"); let guard = span.enter(); - let implementation_inline_fragment = - InlineFragment::new(InlineFragmentData { - schema: self - .graph - .schema_by_source(&tail_weight.source)? - .clone(), - parent_type_position: tail_type_pos.clone().into(), - type_condition_position: Some( - implementation_type_pos.clone().into(), - ), - directives: Default::default(), - selection_id: SelectionId::new(), - }); + let implementation_inline_fragment = InlineFragment { + schema: self.graph.schema_by_source(&tail_weight.source)?.clone(), + parent_type_position: tail_type_pos.clone().into(), + type_condition_position: Some( + implementation_type_pos.clone().into(), + ), + directives: Default::default(), + selection_id: SelectionId::new(), + }; let implementation_options = SimultaneousPathsWithLazyIndirectPaths::new( self.clone().into(), @@ -2909,19 +2903,15 @@ impl OpGraphPath { for implementation_type_pos in intersection { let span = debug_span!("Trying {implementation_type_pos}"); let guard = span.enter(); - let implementation_inline_fragment = - InlineFragment::new(InlineFragmentData { - schema: self - .graph - .schema_by_source(&tail_weight.source)? - .clone(), - parent_type_position: tail_type_pos.clone().into(), - type_condition_position: Some( - implementation_type_pos.clone().into(), - ), - directives: operation_inline_fragment.directives.clone(), - selection_id: SelectionId::new(), - }); + let implementation_inline_fragment = InlineFragment { + schema: self.graph.schema_by_source(&tail_weight.source)?.clone(), + parent_type_position: tail_type_pos.clone().into(), + type_condition_position: Some( + implementation_type_pos.clone().into(), + ), + directives: operation_inline_fragment.directives.clone(), + selection_id: SelectionId::new(), + }; let implementation_options = SimultaneousPathsWithLazyIndirectPaths::new( self.clone().into(), @@ -2995,17 +2985,16 @@ impl OpGraphPath { if operation_inline_fragment.directives.is_empty() { return Ok((Some(vec![self.clone().into()]), None)); } - let operation_inline_fragment = - InlineFragment::new(InlineFragmentData { - schema: self - .graph - .schema_by_source(&tail_weight.source)? - .clone(), - parent_type_position: tail_type_pos.clone().into(), - type_condition_position: None, - directives: operation_inline_fragment.directives.clone(), - selection_id: SelectionId::new(), - }); + let operation_inline_fragment = InlineFragment { + schema: self + .graph + .schema_by_source(&tail_weight.source)? + .clone(), + parent_type_position: tail_type_pos.clone().into(), + type_condition_position: None, + directives: operation_inline_fragment.directives.clone(), + selection_id: SelectionId::new(), + }; let defer_directive_arguments = operation_inline_fragment.defer_directive_arguments()?; let fragment_path = self.add( @@ -3898,7 +3887,6 @@ mod tests { use petgraph::stable_graph::NodeIndex; use crate::operation::Field; - use crate::operation::FieldData; use crate::query_graph::build_query_graph::build_query_graph; use crate::query_graph::condition_resolver::ConditionResolution; use crate::query_graph::graph_path::OpGraphPath; @@ -3934,8 +3922,8 @@ mod tests { type_name: Name::new("T").unwrap(), field_name: Name::new("t").unwrap(), }; - let data = FieldData::from_position(&schema, pos.into()); - let trigger = OpGraphPathTrigger::OpPathElement(OpPathElement::Field(Field::new(data))); + let field = Field::from_position(&schema, pos.into()); + let trigger = OpGraphPathTrigger::OpPathElement(OpPathElement::Field(field)); let path = path .add( trigger, @@ -3952,8 +3940,8 @@ mod tests { type_name: Name::new("ID").unwrap(), field_name: Name::new("id").unwrap(), }; - let data = FieldData::from_position(&schema, pos.into()); - let trigger = OpGraphPathTrigger::OpPathElement(OpPathElement::Field(Field::new(data))); + let field = Field::from_position(&schema, pos.into()); + let trigger = OpGraphPathTrigger::OpPathElement(OpPathElement::Field(field)); let path = path .add( trigger, diff --git a/apollo-federation/src/query_graph/path_tree.rs b/apollo-federation/src/query_graph/path_tree.rs index cb6b9fef18..cf758bed37 100644 --- a/apollo-federation/src/query_graph/path_tree.rs +++ b/apollo-federation/src/query_graph/path_tree.rs @@ -480,7 +480,6 @@ mod tests { use crate::error::FederationError; use crate::operation::normalize_operation; use crate::operation::Field; - use crate::operation::FieldData; use crate::query_graph::build_query_graph::build_query_graph; use crate::query_graph::condition_resolver::ConditionResolution; use crate::query_graph::graph_path::OpGraphPath; @@ -546,7 +545,7 @@ mod tests { .unwrap(); // build the trigger for the edge - let data = FieldData { + let field = Field { schema: query_graph.schema().unwrap().clone(), field_position: field_def.clone(), alias: None, @@ -554,7 +553,7 @@ mod tests { directives: Default::default(), sibling_typename: None, }; - let trigger = OpGraphPathTrigger::OpPathElement(OpPathElement::Field(Field::new(data))); + let trigger = OpGraphPathTrigger::OpPathElement(OpPathElement::Field(field)); // add the edge to the path graph_path = graph_path diff --git a/apollo-federation/src/query_plan/fetch_dependency_graph.rs b/apollo-federation/src/query_plan/fetch_dependency_graph.rs index 5629183fd5..ffffcba928 100644 --- a/apollo-federation/src/query_plan/fetch_dependency_graph.rs +++ b/apollo-federation/src/query_plan/fetch_dependency_graph.rs @@ -36,9 +36,7 @@ use crate::operation::ArgumentList; use crate::operation::ContainmentOptions; use crate::operation::DirectiveList; use crate::operation::Field; -use crate::operation::FieldData; use crate::operation::InlineFragment; -use crate::operation::InlineFragmentData; use crate::operation::InlineFragmentSelection; use crate::operation::Operation; use crate::operation::Selection; @@ -587,7 +585,6 @@ impl FetchDependencyGraphNodePath { fn advance_field_type(&self, element: &Field) -> Result, FederationError> { if !element - .data() .output_base_type() .map(|base_type| base_type.is_composite_type()) .unwrap_or_default() @@ -660,7 +657,7 @@ impl FetchDependencyGraphNodePath { } new_path.push(FetchDataPathElement::Key( - field.response_name(), + field.response_name().clone(), Default::default(), )); @@ -2952,7 +2949,7 @@ fn operation_for_entities_fetch( let entities = FieldDefinitionPosition::Object(query_type.field(ENTITIES_QUERY.clone())); let entities_call = Selection::from_element( - OpPathElement::Field(Field::new(FieldData { + OpPathElement::Field(Field { schema: subgraph_schema.clone(), field_position: entities, alias: None, @@ -2962,7 +2959,7 @@ fn operation_for_entities_fetch( )), directives: Default::default(), sibling_typename: None, - })), + }), Some(selection_set), )?; @@ -3897,13 +3894,13 @@ fn wrap_selection_with_type_and_conditions( // PORT_NOTE: JS code looks for type condition in the wrapping type's schema based on // the name of wrapping type. Not sure why. return wrap_in_fragment( - InlineFragment::new(InlineFragmentData { + InlineFragment { schema: supergraph_schema.clone(), parent_type_position: wrapping_type.clone(), type_condition_position: Some(type_condition.clone()), directives: Default::default(), // None selection_id: SelectionId::new(), - }), + }, initial, ); } @@ -3924,13 +3921,13 @@ fn wrap_selection_with_type_and_conditions( .into()], }; wrap_in_fragment( - InlineFragment::new(InlineFragmentData { + InlineFragment { schema: supergraph_schema.clone(), parent_type_position: wrapping_type.clone(), type_condition_position: Some(type_condition.clone()), directives: [directive].into_iter().collect(), selection_id: SelectionId::new(), - }), + }, acc, ) }) @@ -4770,7 +4767,7 @@ mod tests { object: Name, field: Name, ) -> OpPathElement { - OpPathElement::Field(super::Field::new(FieldData { + OpPathElement::Field(Field { schema: schema.clone(), field_position: ObjectTypeDefinitionPosition::new(object) .field(field) @@ -4779,7 +4776,7 @@ mod tests { arguments: Default::default(), directives: Default::default(), sibling_typename: None, - })) + }) } fn inline_fragment_element( @@ -4794,13 +4791,13 @@ mod tests { .unwrap(); let type_condition = type_condition_name.map(|n| schema.get_type(n).unwrap().try_into().unwrap()); - OpPathElement::InlineFragment(super::InlineFragment::new(InlineFragmentData { + OpPathElement::InlineFragment(InlineFragment { schema: schema.clone(), parent_type_position: parent_type, type_condition_position: type_condition, directives: Default::default(), selection_id: SelectionId::new(), - })) + }) } fn to_string(response_path: &[FetchDataPathElement]) -> String { diff --git a/deny.toml b/deny.toml index 915ca9e58c..55cd3fb0f0 100644 --- a/deny.toml +++ b/deny.toml @@ -53,7 +53,8 @@ allow = [ "MIT", "MPL-2.0", "Elastic-2.0", - "Unicode-DFS-2016" + "Unicode-DFS-2016", + "Zlib" ] copyleft = "warn" allow-osi-fsf-free = "neither" From b7439d7efb8810c0fb3fb61953a8ae686b5b768c Mon Sep 17 00:00:00 2001 From: Andrew Carlson <5479270+andrewicarlson@users.noreply.github.com> Date: Wed, 13 Nov 2024 11:03:13 -0600 Subject: [PATCH 32/77] Added 2 mermaid diagrams to demonstrate entity caching and entity cache invalidation --- .../routing/performance/caching/entity.mdx | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/docs/source/routing/performance/caching/entity.mdx b/docs/source/routing/performance/caching/entity.mdx index 218e6bd12a..d251c19e7e 100644 --- a/docs/source/routing/performance/caching/entity.mdx +++ b/docs/source/routing/performance/caching/entity.mdx @@ -61,6 +61,86 @@ With entity caching enabled for this example, the router can: - Cache the cart per user, with a small amount of data. - Cache inventory data with a short TTL or not cache it at all. +```mermaid +--- +title: Entity Caching using the "Price" entity +--- +flowchart RL + subgraph QueryResponse["JSON Response"] + n1["{ +   "products": [ +     { +       "name": "DraftSnowboard", +       "pastPurchases": ..., +       "price": { +         "amount": "1500", +         "currency_code": "USD" +       }, +       "quantity": "250" +     }, +     ... +   ] + }"] + end + + + + subgraph Subgraphs["Subgraphs"] + Purchases["Purchases"] + Inventory["Inventory"] + Price["Price"] + end + + subgraph PriceQueryFragment["Price Query Fragment (e.g. TTL 2200)"] + n2["{ +   "price": { +     "id": 101, +     "product_id": 12, +     "amount": 1500, +     "currency_code": "USD" +   } + }"] + end + + subgraph PurchaseHistoryQueryFragment["Purchase History Query Fragment"] + n3["{ +   "purchases": { +     "product_id": 12, +     "user_id": 2932, +     ... +   } + }"] + end + + subgraph InventoryQueryFragment["Inventory Query Fragment"] + n4["{ +   "inventory": { +     "id": 19, +     "product_id": 12, +     "quantity": 250 +   } + }"] + end + + Router + Database[("   ")] + + Router --> QueryResponse + Purchases --> Router + Inventory --> Router + Price --- Router + PriceQueryFragment --> Database + PurchaseHistoryQueryFragment --> Purchases + InventoryQueryFragment --> Inventory + Database --> Router + + style n1 text-align:left + style n2 text-align:left + style n3 text-align:left + style n4 text-align:left + style Price border:none,stroke-width:1px,stroke-dasharray:5 5,stroke:#A6A6A6 +``` + ## Use entity caching Follow this guide to enable and configure entity caching in the GraphOS Router. @@ -135,6 +215,54 @@ This entry contains an object with the `all` field to affect all subgraph reques ### Entity cache invalidation +```mermaid +%%{init: {"flowchart": {"htmlLabels": false}} }%% +flowchart RL + subgraph QueryResponse["Cache invalidation POST"] + n1["{ +   "kind": "subgraph", +   "subgraph": "price", +   "type": "Price", +   "key": { +     "id": "101" +   } + }"] + end + + subgraph Subgraphs["Subgraphs"] + Purchases["Purchases"] + Inventory["Inventory"] + Price["Price"] + end + + subgraph PriceQueryFragment["Price Query Fragment (e.g. TTL 2200)"] + n2["` ฬถ{ฬถ +   " ฬถpฬถrฬถiฬถcฬถeฬถ": ฬถ{ฬถ +     " ฬถiฬถdฬถ": ฬถ1ฬถ0ฬถ1ฬถ, +     " ฬถpฬถrฬถoฬถdฬถuฬถcฬถtฬถ_ฬถiฬถdฬถ": ฬถ1ฬถ2ฬถ, +     " ฬถaฬถmฬถoฬถuฬถnฬถtฬถ": ฬถ1ฬถ5ฬถ0ฬถ0ฬถ, +     "ฬถcฬถuฬถrฬถrฬถeฬถnฬถcฬถyฬถ_ฬถcฬถoฬถdฬถeฬถ": " ฬถUฬถSฬถDฬถ" +    ฬถ}ฬถ + ฬถ}ฬถ`"] + end + + Router + Database[("   ")] + + Router --> QueryResponse + Purchases --> Router + Inventory --> Router + Price --- Router + PriceQueryFragment --> Database + Database --> Router + + style n1 text-align:left + style Price border:none,stroke-width:1px,stroke-dasharray:5 5,stroke:#A6A6A6 + style Purchases border:none,stroke-width:1px,stroke-dasharray:5 5,stroke:#A6A6A6 + style Inventory border:none,stroke-width:1px,stroke-dasharray:5 5,stroke:#A6A6A6 + style n2 text-align:left +``` + When existing cache entries need to be replaced, the router supports a couple of ways for you to invalidate entity cache entries: - [**Invalidation endpoint**](#invalidation-http-endpoint) - the router exposes an invalidation endpoint that can receive invalidation requests from any authorized service. This is primarily intended as an alternative to the extensions mechanism described below. For example a subgraph could use it to trigger invalidation events "out of band" from any requests received by the router or a platform operator could use it to invalidate cache entries in response to events which aren't directly related to a router. - **Subgraph response extensions** - you can send invalidation requests via subgraph response extensions, allowing a subgraph to invalidate cached data right after a mutation. From ec54fb3c3bf9eca9e5c3500e0482559db8cf5d95 Mon Sep 17 00:00:00 2001 From: Iryna Shestak Date: Wed, 13 Nov 2024 19:18:23 +0100 Subject: [PATCH 33/77] Enable `generate_query_fragments` by default (#6013) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Renรฉe --- ...ble_generate_query_fragments_by_default.md | 26 +++ .../src/query_plan/query_planner.rs | 25 ++- .../build_query_plan_tests/named_fragments.rs | 14 ++ .../named_fragments_preservation.rs | 21 ++- apollo-router-benchmarks/src/shared.rs | 2 +- ...factory__tests__defer_is_not_buffered.snap | 2 +- apollo-router/src/axum_factory/tests.rs | 2 +- apollo-router/src/configuration/mod.rs | 10 +- ...nfiguration__tests__schema_generation.snap | 4 +- apollo-router/src/plugin/test/mock/canned.rs | 2 +- .../src/plugins/authorization/tests.rs | 2 +- apollo-router/src/plugins/cache/tests.rs | 6 +- .../src/plugins/expose_query_plan.rs | 12 ++ .../src/plugins/include_subgraph_errors.rs | 28 +-- .../src/plugins/traffic_shaping/mod.rs | 3 + apollo-router/src/query_planner/tests.rs | 40 ++++- ...sts__escaped_quotes_in_string_literal.snap | 2 +- .../src/services/supergraph/tests.rs | 159 ++++++++++++++++-- .../fixtures/type_conditions/artwork.json | 4 +- .../type_conditions/artwork_disabled.json | 4 +- .../fixtures/type_conditions/search.json | 2 +- .../type_conditions/search_list_of_list.json | 4 +- .../search_list_of_list_of_list.json | 4 +- ..._config_update_query_fragments.router.yaml | 4 +- apollo-router/tests/integration/redis.rs | 26 ++- .../tests/samples/core/defer/plan.json | 4 +- .../enterprise/entity-cache/defer/plan.json | 4 +- .../invalidation-entity-key/plan.json | 8 +- apollo-router/tests/set_context.rs | 4 + ...ons___test_type_conditions_disabled-2.snap | 10 +- ...tions___test_type_conditions_disabled.snap | 10 +- ...ions___test_type_conditions_enabled-2.snap | 14 +- ...itions___test_type_conditions_enabled.snap | 14 +- ...ype_conditions_enabled_list_of_list-2.snap | 14 +- ..._type_conditions_enabled_list_of_list.snap | 14 +- ...itions_enabled_list_of_list_of_list-2.snap | 14 +- ...nditions_enabled_list_of_list_of_list.snap | 14 +- apollo-router/tests/tracing_common/mod.rs | 10 +- apollo-router/tests/type_conditions.rs | 7 +- .../source/reference/router/configuration.mdx | 25 ++- 40 files changed, 423 insertions(+), 151 deletions(-) create mode 100644 .changesets/feat_lrlna_enable_generate_query_fragments_by_default.md diff --git a/.changesets/feat_lrlna_enable_generate_query_fragments_by_default.md b/.changesets/feat_lrlna_enable_generate_query_fragments_by_default.md new file mode 100644 index 0000000000..2ae65008fd --- /dev/null +++ b/.changesets/feat_lrlna_enable_generate_query_fragments_by_default.md @@ -0,0 +1,26 @@ +### Compress subgraph operations by generating fragments + +The router now compresses operations sent to subgraphs by default by generating fragment +definitions and using them in the operation. + +Initially, the router is using a very simple transformation that is implemented in both +the JavaScript and Native query planners. We will improve the algorithm after the JavaScript +planner is no longer supported. + +This replaces a previous experimental algorithm that was enabled by default. +`experimental_reuse_query_fragments` attempted to intelligently reuse the fragment definitions +from the original operation. Fragment generation is much faster, and in most cases produces +better outputs too. + +If you are relying on the shape of fragments in your subgraph operations or tests, you can opt +out of the new algorithm with the configuration below. Note we strongly recommend against +relying on the shape of planned operations as new router features and optimizations may affect +it, and we intend to remove `experimental_reuse_query_fragments` in a future release. + +```yaml +supergraph: + generate_query_fragments: false + experimental_reuse_query_fragments: true +``` + +By [@lrlna](https://github.com/lrlna) in https://github.com/apollographql/router/pull/6013 diff --git a/apollo-federation/src/query_plan/query_planner.rs b/apollo-federation/src/query_plan/query_planner.rs index 1a3f1002f1..f6f4062760 100644 --- a/apollo-federation/src/query_plan/query_planner.rs +++ b/apollo-federation/src/query_plan/query_planner.rs @@ -63,7 +63,7 @@ pub struct QueryPlannerConfig { /// queries with many fragments. This option may be removed in the future in favour of /// [`generate_query_fragments`][QueryPlannerConfig::generate_query_fragments]. /// - /// Defaults to true. + /// Defaults to false. pub reuse_query_fragments: bool, /// If enabled, the query planner will extract inline fragments into fragment @@ -103,15 +103,16 @@ pub struct QueryPlannerConfig { pub type_conditioned_fetching: bool, } +#[allow(clippy::derivable_impls)] // it's derivable right now, but we might change the defaults impl Default for QueryPlannerConfig { fn default() -> Self { Self { - reuse_query_fragments: true, + reuse_query_fragments: false, generate_query_fragments: false, subgraph_graphql_validation: false, incremental_delivery: Default::default(), debug: Default::default(), - type_conditioned_fetching: Default::default(), + type_conditioned_fetching: false, } } } @@ -1381,7 +1382,11 @@ type User ) .unwrap(); - let planner = QueryPlanner::new(&supergraph, Default::default()).unwrap(); + let config = QueryPlannerConfig { + reuse_query_fragments: true, + ..Default::default() + }; + let planner = QueryPlanner::new(&supergraph, config).unwrap(); let plan = planner .build_query_plan(&document, None, Default::default()) .unwrap(); @@ -1442,7 +1447,11 @@ type User ) .unwrap(); - let planner = QueryPlanner::new(&supergraph, Default::default()).unwrap(); + let config = QueryPlannerConfig { + reuse_query_fragments: true, + ..Default::default() + }; + let planner = QueryPlanner::new(&supergraph, config).unwrap(); let plan = planner .build_query_plan(&document, None, Default::default()) .unwrap(); @@ -1504,7 +1513,11 @@ type User ) .unwrap(); - let planner = QueryPlanner::new(&supergraph, Default::default()).unwrap(); + let config = QueryPlannerConfig { + reuse_query_fragments: true, + ..Default::default() + }; + let planner = QueryPlanner::new(&supergraph, config).unwrap(); let plan = planner .build_query_plan(&document, None, Default::default()) .unwrap(); diff --git a/apollo-federation/tests/query_plan/build_query_plan_tests/named_fragments.rs b/apollo-federation/tests/query_plan/build_query_plan_tests/named_fragments.rs index a2d8b785f7..959069588c 100644 --- a/apollo-federation/tests/query_plan/build_query_plan_tests/named_fragments.rs +++ b/apollo-federation/tests/query_plan/build_query_plan_tests/named_fragments.rs @@ -1,6 +1,16 @@ +use apollo_federation::query_plan::query_planner::QueryPlannerConfig; + +fn reuse_fragments_config() -> QueryPlannerConfig { + QueryPlannerConfig { + reuse_query_fragments: true, + ..Default::default() + } +} + #[test] fn handles_mix_of_fragments_indirection_and_unions() { let planner = planner!( + config = reuse_fragments_config(), Subgraph1: r#" type Query { parent: Parent @@ -74,6 +84,7 @@ fn another_mix_of_fragments_indirection_and_unions() { // This tests that the issue reported on https://github.com/apollographql/router/issues/3172 is resolved. let planner = planner!( + config = reuse_fragments_config(), Subgraph1: r#" type Query { owner: Owner! @@ -252,6 +263,7 @@ fn another_mix_of_fragments_indirection_and_unions() { #[test] fn handles_fragments_with_interface_field_subtyping() { let planner = planner!( + config = reuse_fragments_config(), Subgraph1: r#" type Query { t1: T1! @@ -313,6 +325,7 @@ fn handles_fragments_with_interface_field_subtyping() { #[test] fn can_reuse_fragments_in_subgraph_where_they_only_partially_apply_in_root_fetch() { let planner = planner!( + config = reuse_fragments_config(), Subgraph1: r#" type Query { t1: T @@ -416,6 +429,7 @@ fn can_reuse_fragments_in_subgraph_where_they_only_partially_apply_in_root_fetch #[test] fn can_reuse_fragments_in_subgraph_where_they_only_partially_apply_in_entity_fetch() { let planner = planner!( + config = reuse_fragments_config(), Subgraph1: r#" type Query { t: T diff --git a/apollo-federation/tests/query_plan/build_query_plan_tests/named_fragments_preservation.rs b/apollo-federation/tests/query_plan/build_query_plan_tests/named_fragments_preservation.rs index 5633ba79b6..da90c3edb8 100644 --- a/apollo-federation/tests/query_plan/build_query_plan_tests/named_fragments_preservation.rs +++ b/apollo-federation/tests/query_plan/build_query_plan_tests/named_fragments_preservation.rs @@ -1,8 +1,16 @@ use apollo_federation::query_plan::query_planner::QueryPlannerConfig; +fn reuse_fragments_config() -> QueryPlannerConfig { + QueryPlannerConfig { + reuse_query_fragments: true, + ..Default::default() + } +} + #[test] fn it_works_with_nested_fragments_1() { let planner = planner!( + config = reuse_fragments_config(), Subgraph1: r#" type Query { a: Anything @@ -127,6 +135,7 @@ fn it_works_with_nested_fragments_1() { #[test] fn it_avoid_fragments_usable_only_once() { let planner = planner!( + config = reuse_fragments_config(), Subgraph1: r#" type Query { t: T @@ -324,10 +333,9 @@ mod respects_query_planner_option_reuse_query_fragments { #[test] fn respects_query_planner_option_reuse_query_fragments_true() { - let reuse_query_fragments = true; let planner = planner!( - config = QueryPlannerConfig {reuse_query_fragments, ..Default::default()}, - Subgraph1: SUBGRAPH1, + config = reuse_fragments_config(), + Subgraph1: SUBGRAPH1, ); let query = QUERY; @@ -395,6 +403,7 @@ mod respects_query_planner_option_reuse_query_fragments { #[test] fn it_works_with_nested_fragments_when_only_the_nested_fragment_gets_preserved() { let planner = planner!( + config = reuse_fragments_config(), Subgraph1: r#" type Query { t: T @@ -463,6 +472,7 @@ fn it_works_with_nested_fragments_when_only_the_nested_fragment_gets_preserved() fn it_preserves_directives_when_fragment_not_used() { // (because used only once) let planner = planner!( + config = reuse_fragments_config(), Subgraph1: r#" type Query { t: T @@ -511,6 +521,7 @@ fn it_preserves_directives_when_fragment_not_used() { #[test] fn it_preserves_directives_when_fragment_is_reused() { let planner = planner!( + config = reuse_fragments_config(), Subgraph1: r#" type Query { t: T @@ -572,6 +583,7 @@ fn it_does_not_try_to_apply_fragments_that_are_not_valid_for_the_subgraph() { // server would reject it when validating the query, and we must make sure it // is not reused. let planner = planner!( + config = reuse_fragments_config(), Subgraph1: r#" type Query { i1: I @@ -652,6 +664,7 @@ fn it_handles_fragment_rebasing_in_a_subgraph_where_some_subtyping_relation_diff // Previous versions of the code were not handling this case and were error out by // creating the invalid selection (#2721), and this test ensures this is fixed. let planner = planner!( + config = reuse_fragments_config(), Subgraph1: r#" type V @shareable { x: Int @@ -988,6 +1001,7 @@ fn it_handles_fragment_rebasing_in_a_subgraph_where_some_union_membership_relati // This test is similar to the subtyping case (it tests the same problems), but test the case // of unions instead of interfaces. let planner = planner!( + config = reuse_fragments_config(), Subgraph1: r#" type V @shareable { x: Int @@ -1302,6 +1316,7 @@ fn it_handles_fragment_rebasing_in_a_subgraph_where_some_union_membership_relati #[test] fn it_preserves_nested_fragments_when_outer_one_has_directives_and_is_eliminated() { let planner = planner!( + config = reuse_fragments_config(), Subgraph1: r#" type Query { t: T diff --git a/apollo-router-benchmarks/src/shared.rs b/apollo-router-benchmarks/src/shared.rs index cf3e57af9b..e0576c603e 100644 --- a/apollo-router-benchmarks/src/shared.rs +++ b/apollo-router-benchmarks/src/shared.rs @@ -76,7 +76,7 @@ pub fn setup() -> TestHarness<'static> { }}).build(); let review_service = MockSubgraph::builder().with_json(json!{{ - "query": "query TopProducts__reviews__1($representations:[_Any!]!){_entities(representations:$representations){...on Product{reviews{id product{__typename upc}author{__typename id}}}}}", + "query": "query TopProducts__reviews__1($representations:[_Any!]!){_entities(representations:$representations){..._generated_onProduct1_0}}fragment _generated_onProduct1_0 on Product{reviews{id product{__typename upc}author{__typename id}}}", "operationName": "TopProducts__reviews__1", "variables": { "representations":[ diff --git a/apollo-router/src/axum_factory/snapshots/apollo_router__axum_factory__tests__defer_is_not_buffered.snap b/apollo-router/src/axum_factory/snapshots/apollo_router__axum_factory__tests__defer_is_not_buffered.snap index c08d3d1693..ece5fd3c9f 100644 --- a/apollo-router/src/axum_factory/snapshots/apollo_router__axum_factory__tests__defer_is_not_buffered.snap +++ b/apollo-router/src/axum_factory/snapshots/apollo_router__axum_factory__tests__defer_is_not_buffered.snap @@ -20,7 +20,7 @@ expression: parts }, "errors": [ { - "message": "couldn't find mock for query {\"query\":\"query($representations: [_Any!]!) { _entities(representations: $representations) { ... on Product { reviews { __typename id product { __typename upc } } } } }\",\"variables\":{\"representations\":[{\"__typename\":\"Product\",\"upc\":\"1\"},{\"__typename\":\"Product\",\"upc\":\"2\"}]}}", + "message": "couldn't find mock for query {\"query\":\"query($representations: [_Any!]!) { _entities(representations: $representations) { ..._generated_onProduct1_0 } } fragment _generated_onProduct1_0 on Product { reviews { __typename id product { __typename upc } } }\",\"variables\":{\"representations\":[{\"__typename\":\"Product\",\"upc\":\"1\"},{\"__typename\":\"Product\",\"upc\":\"2\"}]}}", "path": [ "topProducts", "@" diff --git a/apollo-router/src/axum_factory/tests.rs b/apollo-router/src/axum_factory/tests.rs index 87198b8f4f..efcf7e3ab3 100644 --- a/apollo-router/src/axum_factory/tests.rs +++ b/apollo-router/src/axum_factory/tests.rs @@ -1847,7 +1847,7 @@ async fn http_compressed_service() -> impl Service< "apollo.include_subgraph_errors": { "all": true } - } + }, })) .unwrap() .supergraph_hook(move |service| { diff --git a/apollo-router/src/configuration/mod.rs b/apollo-router/src/configuration/mod.rs index 85de05cd8f..c561a131f9 100644 --- a/apollo-router/src/configuration/mod.rs +++ b/apollo-router/src/configuration/mod.rs @@ -681,7 +681,7 @@ pub(crate) struct Supergraph { pub(crate) reuse_query_fragments: Option, /// Enable QP generation of fragments for subgraph requests - /// Default: false + /// Default: true pub(crate) generate_query_fragments: bool, /// Set to false to disable defer support @@ -701,6 +701,10 @@ pub(crate) struct Supergraph { pub(crate) experimental_log_on_broken_pipe: bool, } +const fn default_generate_query_fragments() -> bool { + true +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, Deserialize, Serialize, JsonSchema)] #[serde(rename_all = "snake_case", untagged)] pub(crate) enum AvailableParallelism { @@ -753,7 +757,7 @@ impl Supergraph { Some(false) } else { reuse_query_fragments } ), - generate_query_fragments: generate_query_fragments.unwrap_or_default(), + generate_query_fragments: generate_query_fragments.unwrap_or_else(default_generate_query_fragments), early_cancel: early_cancel.unwrap_or_default(), experimental_log_on_broken_pipe: experimental_log_on_broken_pipe.unwrap_or_default(), } @@ -790,7 +794,7 @@ impl Supergraph { Some(false) } else { reuse_query_fragments } ), - generate_query_fragments: generate_query_fragments.unwrap_or_default(), + generate_query_fragments: generate_query_fragments.unwrap_or_else(default_generate_query_fragments), early_cancel: early_cancel.unwrap_or_default(), experimental_log_on_broken_pipe: experimental_log_on_broken_pipe.unwrap_or_default(), } 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 817d67517a..35913d1ce2 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 @@ -6604,8 +6604,8 @@ expression: "&schema" "type": "boolean" }, "generate_query_fragments": { - "default": false, - "description": "Enable QP generation of fragments for subgraph requests Default: false", + "default": true, + "description": "Enable QP generation of fragments for subgraph requests Default: true", "type": "boolean" }, "introspection": { diff --git a/apollo-router/src/plugin/test/mock/canned.rs b/apollo-router/src/plugin/test/mock/canned.rs index 099f494f0c..369715444e 100644 --- a/apollo-router/src/plugin/test/mock/canned.rs +++ b/apollo-router/src/plugin/test/mock/canned.rs @@ -52,7 +52,7 @@ pub(crate) fn reviews_subgraph() -> MockSubgraph { let review_mocks = vec![ ( json! {{ - "query": "query TopProducts__reviews__1($representations:[_Any!]!){_entities(representations:$representations){...on Product{reviews{id product{__typename upc}author{__typename id}}}}}", + "query": "query TopProducts__reviews__1($representations:[_Any!]!){_entities(representations:$representations){..._generated_onProduct1_0}}fragment _generated_onProduct1_0 on Product{reviews{id product{__typename upc}author{__typename id}}}", "operationName": "TopProducts__reviews__1", "variables": { "representations":[ diff --git a/apollo-router/src/plugins/authorization/tests.rs b/apollo-router/src/plugins/authorization/tests.rs index d967125881..b8b1b8052b 100644 --- a/apollo-router/src/plugins/authorization/tests.rs +++ b/apollo-router/src/plugins/authorization/tests.rs @@ -22,7 +22,7 @@ async fn authenticated_request() { let subgraphs = MockedSubgraphs([ ("user", MockSubgraph::builder().with_json( serde_json::json!{{ - "query": "query($representations:[_Any!]!){_entities(representations:$representations){...on User{name phone}}}", + "query": "query($representations:[_Any!]!){_entities(representations:$representations){..._generated_onUser2_0}}fragment _generated_onUser2_0 on User{name phone}", "variables": { "representations": [ { "__typename": "User", "id":0 } diff --git a/apollo-router/src/plugins/cache/tests.rs b/apollo-router/src/plugins/cache/tests.rs index 64c96a0763..24dc71d3ab 100644 --- a/apollo-router/src/plugins/cache/tests.rs +++ b/apollo-router/src/plugins/cache/tests.rs @@ -160,7 +160,7 @@ async fn insert() { ).with_header(CACHE_CONTROL, HeaderValue::from_static("public")).build()), ("orga", MockSubgraph::builder().with_json( serde_json::json!{{ - "query": "query($representations:[_Any!]!){_entities(representations:$representations){...on Organization{creatorUser{__typename id}}}}", + "query": "query($representations:[_Any!]!){_entities(representations:$representations){..._generated_onOrganization1_0}}fragment _generated_onOrganization1_0 on Organization{creatorUser{__typename id}}", "variables": { "representations": [ { @@ -274,7 +274,7 @@ async fn no_cache_control() { ).build()), ("orga", MockSubgraph::builder().with_json( serde_json::json!{{ - "query": "query($representations:[_Any!]!){_entities(representations:$representations){...on Organization{creatorUser{__typename id}}}}", + "query": "query($representations:[_Any!]!){_entities(representations:$representations){..._generated_onOrganization1_0}}fragment _generated_onOrganization1_0 on Organization{creatorUser{__typename id}}", "variables": { "representations": [ { @@ -365,7 +365,7 @@ async fn private() { .build()), ("orga", MockSubgraph::builder().with_json( serde_json::json!{{ - "query": "query($representations:[_Any!]!){_entities(representations:$representations){...on Organization{creatorUser{__typename id}}}}", + "query": "query($representations:[_Any!]!){_entities(representations:$representations){..._generated_onOrganization1_0}}fragment _generated_onOrganization1_0 on Organization{creatorUser{__typename id}}", "variables": { "representations": [ { diff --git a/apollo-router/src/plugins/expose_query_plan.rs b/apollo-router/src/plugins/expose_query_plan.rs index 78d771554c..657969e27c 100644 --- a/apollo-router/src/plugins/expose_query_plan.rs +++ b/apollo-router/src/plugins/expose_query_plan.rs @@ -218,6 +218,10 @@ mod tests { build_mock_supergraph(serde_json::json! {{ "plugins": { "experimental.expose_query_plan": true + }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, } }}) .await, @@ -231,6 +235,10 @@ mod tests { build_mock_supergraph(serde_json::json! {{ "plugins": { "experimental.expose_query_plan": true + }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, } }}) .await, @@ -245,6 +253,10 @@ mod tests { let supergraph = build_mock_supergraph(serde_json::json! {{ "plugins": { "experimental.expose_query_plan": false + }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, } }}) .await; diff --git a/apollo-router/src/plugins/include_subgraph_errors.rs b/apollo-router/src/plugins/include_subgraph_errors.rs index 34348f4ef7..3b399e0151 100644 --- a/apollo-router/src/plugins/include_subgraph_errors.rs +++ b/apollo-router/src/plugins/include_subgraph_errors.rs @@ -191,13 +191,19 @@ mod test { let product_service = MockSubgraph::new(product_mocks).with_extensions(extensions); + let mut configuration = Configuration::default(); + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + configuration.supergraph.generate_query_fragments = false; + let configuration = Arc::new(configuration); + let schema = include_str!("../../../apollo-router-benchmarks/benches/fixtures/supergraph.graphql"); - let schema = Schema::parse(schema, &Default::default()).unwrap(); + let schema = Schema::parse(schema, &configuration).unwrap(); + let planner = BridgeQueryPlannerPool::new( Vec::new(), schema.into(), - Default::default(), + Arc::clone(&configuration), NonZeroUsize::new(1).unwrap(), ) .await @@ -207,15 +213,9 @@ mod test { let builder = PluggableSupergraphServiceBuilder::new(planner); - let mut plugins = create_plugins( - &Configuration::default(), - &schema, - subgraph_schemas, - None, - None, - ) - .await - .unwrap(); + let mut plugins = create_plugins(&configuration, &schema, subgraph_schemas, None, None) + .await + .unwrap(); plugins.insert("apollo.include_subgraph_errors".to_string(), plugin); @@ -228,10 +228,10 @@ mod test { let supergraph_creator = builder.build().await.expect("should build"); RouterCreator::new( - QueryAnalysisLayer::new(supergraph_creator.schema(), Default::default()).await, - Arc::new(PersistedQueryLayer::new(&Default::default()).await.unwrap()), + QueryAnalysisLayer::new(supergraph_creator.schema(), Arc::clone(&configuration)).await, + Arc::new(PersistedQueryLayer::new(&configuration).await.unwrap()), Arc::new(supergraph_creator), - Arc::new(Configuration::default()), + configuration, ) .await .unwrap() diff --git a/apollo-router/src/plugins/traffic_shaping/mod.rs b/apollo-router/src/plugins/traffic_shaping/mod.rs index 1125239d10..4335bfe988 100644 --- a/apollo-router/src/plugins/traffic_shaping/mod.rs +++ b/apollo-router/src/plugins/traffic_shaping/mod.rs @@ -578,6 +578,9 @@ mod test { r#" traffic_shaping: deduplicate_variables: true + supergraph: + # TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + generate_query_fragments: false "#, ) .unwrap(); diff --git a/apollo-router/src/query_planner/tests.rs b/apollo-router/src/query_planner/tests.rs index 131dc7ba12..766ce9a715 100644 --- a/apollo-router/src/query_planner/tests.rs +++ b/apollo-router/src/query_planner/tests.rs @@ -821,7 +821,13 @@ async fn alias_renaming() { ].into_iter().collect()); let service = TestHarness::builder() - .configuration_json(serde_json::json!({"include_subgraph_errors": { "all": true } })) + .configuration_json(serde_json::json!({ + "include_subgraph_errors": { "all": true }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, + } + })) .unwrap() .schema(schema) .extra_plugin(subgraphs) @@ -1264,7 +1270,13 @@ async fn missing_typename_and_fragments_in_requires2() { ].into_iter().collect()); let service = TestHarness::builder() - .configuration_json(serde_json::json!({"include_subgraph_errors": { "all": true } })) + .configuration_json(serde_json::json!({ + "include_subgraph_errors": { "all": true }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, + } + })) .unwrap() .schema(schema) .extra_plugin(subgraphs) @@ -1551,7 +1563,13 @@ async fn typename_propagation() { ); let service = TestHarness::builder() - .configuration_json(serde_json::json!({"include_subgraph_errors": { "all": true } })) + .configuration_json(serde_json::json!({ + "include_subgraph_errors": { "all": true }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, + } + })) .unwrap() .schema(TYPENAME_PROPAGATION_SCHEMA) .extra_plugin(subgraphs) @@ -1648,7 +1666,13 @@ async fn typename_propagation2() { ); let service = TestHarness::builder() - .configuration_json(serde_json::json!({"include_subgraph_errors": { "all": true } })) + .configuration_json(serde_json::json!({ + "include_subgraph_errors": { "all": true }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, + } + })) .unwrap() .schema(TYPENAME_PROPAGATION_SCHEMA) .extra_plugin(subgraphs) @@ -1746,7 +1770,13 @@ async fn typename_propagation3() { ); let service = TestHarness::builder() - .configuration_json(serde_json::json!({"include_subgraph_errors": { "all": true } })) + .configuration_json(serde_json::json!({ + "include_subgraph_errors": { "all": true }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, + } + })) .unwrap() .schema(TYPENAME_PROPAGATION_SCHEMA) .extra_plugin(subgraphs) diff --git a/apollo-router/src/services/router/snapshots/apollo_router__services__router__tests__escaped_quotes_in_string_literal.snap b/apollo-router/src/services/router/snapshots/apollo_router__services__router__tests__escaped_quotes_in_string_literal.snap index 9fcfad90a4..4c8165c12c 100644 --- a/apollo-router/src/services/router/snapshots/apollo_router__services__router__tests__escaped_quotes_in_string_literal.snap +++ b/apollo-router/src/services/router/snapshots/apollo_router__services__router__tests__escaped_quotes_in_string_literal.snap @@ -41,7 +41,7 @@ expression: "(graphql_response, &subgraph_query_log)" ( "reviews", Some( - "query TopProducts__reviews__1($representations:[_Any!]!){_entities(representations:$representations){...on Product{reviewsForAuthor(authorID:\"\\\"1\\\"\"){body}}}}", + "query TopProducts__reviews__1($representations:[_Any!]!){_entities(representations:$representations){..._generated_onProduct1_0}}fragment _generated_onProduct1_0 on Product{reviewsForAuthor(authorID:\"\\\"1\\\"\"){body}}", ), ), ], diff --git a/apollo-router/src/services/supergraph/tests.rs b/apollo-router/src/services/supergraph/tests.rs index b62b83737b..ac2dbab21a 100644 --- a/apollo-router/src/services/supergraph/tests.rs +++ b/apollo-router/src/services/supergraph/tests.rs @@ -655,7 +655,13 @@ async fn deferred_fragment_bounds_nullability() { ].into_iter().collect()); let service = TestHarness::builder() - .configuration_json(serde_json::json!({"include_subgraph_errors": { "all": true } })) + .configuration_json(serde_json::json!({ + "include_subgraph_errors": { "all": true }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, + } + })) .unwrap() .schema(SCHEMA) .extra_plugin(subgraphs) @@ -737,7 +743,13 @@ async fn errors_on_incremental_responses() { ].into_iter().collect()); let service = TestHarness::builder() - .configuration_json(serde_json::json!({"include_subgraph_errors": { "all": true } })) + .configuration_json(serde_json::json!({ + "include_subgraph_errors": { "all": true }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, + } + })) .unwrap() .schema(SCHEMA) .extra_plugin(subgraphs) @@ -809,7 +821,13 @@ async fn root_typename_with_defer() { ].into_iter().collect()); let service = TestHarness::builder() - .configuration_json(serde_json::json!({"include_subgraph_errors": { "all": true } })) + .configuration_json(serde_json::json!({ + "include_subgraph_errors": { "all": true }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, + } + })) .unwrap() .schema(SCHEMA) .extra_plugin(subgraphs) @@ -867,7 +885,18 @@ async fn subscription_with_callback() { ).build()) ].into_iter().collect()); - let mut configuration: Configuration = serde_json::from_value(serde_json::json!({"include_subgraph_errors": { "all": true }, "subscription": { "enabled": true, "mode": {"callback": {"public_url": "http://localhost:4545/callback"}}}})).unwrap(); + let mut configuration: Configuration = serde_json::from_value(serde_json::json!({ + "include_subgraph_errors": { "all": true }, + "subscription": { + "enabled": true, + "mode": {"callback": {"public_url": "http://localhost:4545/callback"}} + }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, + } + })) + .unwrap(); configuration.notify = notify.clone(); let service = TestHarness::builder() .configuration(Arc::new(configuration)) @@ -942,7 +971,23 @@ async fn subscription_callback_schema_reload() { ("orga", orga_subgraph) ].into_iter().collect()); - let mut configuration: Configuration = serde_json::from_value(serde_json::json!({"include_subgraph_errors": { "all": true }, "headers": {"all": {"request": [{"propagate": {"named": "x-test"}}]}}, "subscription": { "enabled": true, "mode": {"callback": {"public_url": "http://localhost:4545/callback"}}}})).unwrap(); + let mut configuration: Configuration = serde_json::from_value(serde_json::json!({ + "include_subgraph_errors": { "all": true }, + "headers": { + "all": { + "request": [{"propagate": {"named": "x-test"}}] + } + }, + "subscription": { + "enabled": true, + "mode": {"callback": {"public_url": "http://localhost:4545/callback"}} + }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, + } + })) + .unwrap(); configuration.notify = notify.clone(); let configuration = Arc::new(configuration); let service = TestHarness::builder() @@ -1011,7 +1056,19 @@ async fn subscription_with_callback_with_limit() { ).build()) ].into_iter().collect()); - let mut configuration: Configuration = serde_json::from_value(serde_json::json!({"include_subgraph_errors": { "all": true }, "subscription": { "enabled": true, "max_opened_subscriptions": 1, "mode": {"callback": {"public_url": "http://localhost:4545/callback"}}}})).unwrap(); + let mut configuration: Configuration = serde_json::from_value(serde_json::json!({ + "include_subgraph_errors": { "all": true }, + "subscription": { + "enabled": true, + "max_opened_subscriptions": 1, + "mode": {"callback": {"public_url": "http://localhost:4545/callback"}} + }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, + } + })) + .unwrap(); configuration.notify = notify.clone(); let mut service = TestHarness::builder() .configuration(Arc::new(configuration)) @@ -1103,12 +1160,29 @@ async fn subscription_without_header() { async fn root_typename_with_defer_and_empty_first_response() { let subgraphs = MockedSubgraphs([ ("user", MockSubgraph::builder().with_json( - serde_json::json!{{"query":"{... on Query{currentUser{activeOrganization{__typename id}}}}"}}, - serde_json::json!{{"data": {"currentUser": { "activeOrganization": { "__typename": "Organization", "id": "0" } }}}} - ).build()), + serde_json::json!{{ + "query": " + { ..._generated_onQuery1_0 } + + fragment _generated_onQuery1_0 on Query { + currentUser { activeOrganization { __typename id} } + } + ", + }}, + serde_json::json!{{"data": {"currentUser": { "activeOrganization": { "__typename": "Organization", "id": "0" } }}}} + ).build()), ("orga", MockSubgraph::builder().with_json( serde_json::json!{{ - "query":"query($representations:[_Any!]!){_entities(representations:$representations){...on Organization{suborga{id name}}}}", + "query": " + query($representations: [_Any!]!) { + _entities(representations: $representations) { + ..._generated_onOrganization1_0 + } + } + fragment _generated_onOrganization1_0 on Organization { + suborga { id name } + } + ", "variables": { "representations":[{"__typename": "Organization", "id":"0"}] } @@ -1216,7 +1290,14 @@ async fn root_typename_with_defer_in_defer() { ).build()), ("orga", MockSubgraph::builder().with_json( serde_json::json!{{ - "query":"query($representations:[_Any!]!){_entities(representations:$representations){...on Organization{suborga{__typename id name}}}}", + "query":" + query($representations:[_Any!]!){ + _entities(representations:$representations) { ..._generated_onOrganization1_0 } + } + fragment _generated_onOrganization1_0 on Organization { + suborga {__typename id name} + } + ", "variables": { "representations":[{"__typename": "Organization", "id":"0"}] } @@ -1453,7 +1534,13 @@ async fn filter_nullified_deferred_responses() { ].into_iter().collect()); let service = TestHarness::builder() - .configuration_json(serde_json::json!({"include_subgraph_errors": { "all": true } })) + .configuration_json(serde_json::json!({ + "include_subgraph_errors": { "all": true }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, + } + })) .unwrap() .schema(SCHEMA) .extra_plugin(subgraphs) @@ -1606,7 +1693,13 @@ async fn reconstruct_deferred_query_under_interface() { ].into_iter().collect()); let service = TestHarness::builder() - .configuration_json(serde_json::json!({"include_subgraph_errors": { "all": true } })) + .configuration_json(serde_json::json!({ + "include_subgraph_errors": { "all": true }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, + } + })) .unwrap() .schema(schema) .extra_plugin(subgraphs) @@ -1775,7 +1868,13 @@ async fn interface_object_typename_rewrites() { ].into_iter().collect()); let service = TestHarness::builder() - .configuration_json(serde_json::json!({"include_subgraph_errors": { "all": true } })) + .configuration_json(serde_json::json!({ + "include_subgraph_errors": { "all": true }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, + } + })) .unwrap() .schema(schema) .extra_plugin(subgraphs) @@ -1913,7 +2012,13 @@ async fn interface_object_response_processing() { ].into_iter().collect()); let service = TestHarness::builder() - .configuration_json(serde_json::json!({"include_subgraph_errors": { "all": true } })) + .configuration_json(serde_json::json!({ + "include_subgraph_errors": { "all": true }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, + } + })) .unwrap() .schema(schema) .extra_plugin(subgraphs) @@ -2182,7 +2287,13 @@ async fn aliased_subgraph_data_rewrites_on_root_fetch() { ].into_iter().collect()); let service = TestHarness::builder() - .configuration_json(serde_json::json!({"include_subgraph_errors": { "all": true } })) + .configuration_json(serde_json::json!({ + "include_subgraph_errors": { "all": true }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, + } + })) .unwrap() .schema(schema) .extra_plugin(subgraphs) @@ -2322,7 +2433,13 @@ async fn aliased_subgraph_data_rewrites_on_non_root_fetch() { ].into_iter().collect()); let service = TestHarness::builder() - .configuration_json(serde_json::json!({"include_subgraph_errors": { "all": true } })) + .configuration_json(serde_json::json!({ + "include_subgraph_errors": { "all": true }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, + } + })) .unwrap() .schema(schema) .extra_plugin(subgraphs) @@ -3295,7 +3412,13 @@ async fn fragment_reuse() { ].into_iter().collect()); let service = TestHarness::builder() - .configuration_json(serde_json::json!({"include_subgraph_errors": { "all": true } })) + .configuration_json(serde_json::json!({ + "include_subgraph_errors": { "all": true }, + "supergraph": { + "generate_query_fragments": false, + "experimental_reuse_query_fragments": true, + } + })) .unwrap() .schema(SCHEMA) .extra_plugin(subgraphs) diff --git a/apollo-router/tests/fixtures/type_conditions/artwork.json b/apollo-router/tests/fixtures/type_conditions/artwork.json index ad5451f398..e4c437c2cd 100644 --- a/apollo-router/tests/fixtures/type_conditions/artwork.json +++ b/apollo-router/tests/fixtures/type_conditions/artwork.json @@ -2,7 +2,7 @@ "mocks": [ { "request": { - "query":"query Search__artworkSubgraph__1($representations:[_Any!]!$movieResultParam:String){_entities(representations:$representations){...on EntityCollectionSection{title artwork(params:$movieResultParam)}...on GallerySection{artwork(params:$movieResultParam)}}}", + "query":"query Search__artworkSubgraph__1($representations:[_Any!]!$movieResultParam:String){_entities(representations:$representations){..._generated_onEntityCollectionSection2_0 ...on GallerySection{artwork(params:$movieResultParam)}}}fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection{title artwork(params:$movieResultParam)}", "operationName":"Search__artworkSubgraph__1", "variables":{ "movieResultParam":"movieResultEnabled", @@ -50,7 +50,7 @@ }, { "request": { - "query": "query Search__artworkSubgraph__2($representations:[_Any!]!$articleResultParam:String){_entities(representations:$representations){...on GallerySection{artwork(params:$articleResultParam)}...on EntityCollectionSection{artwork(params:$articleResultParam)title}}}", + "query": "query Search__artworkSubgraph__2($representations:[_Any!]!$articleResultParam:String){_entities(representations:$representations){...on GallerySection{artwork(params:$articleResultParam)}..._generated_onEntityCollectionSection2_0}}fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection{artwork(params:$articleResultParam)title}", "operationName": "Search__artworkSubgraph__2", "variables":{ "articleResultParam":"articleResultEnabled", diff --git a/apollo-router/tests/fixtures/type_conditions/artwork_disabled.json b/apollo-router/tests/fixtures/type_conditions/artwork_disabled.json index 1552804424..5e230e1e3c 100644 --- a/apollo-router/tests/fixtures/type_conditions/artwork_disabled.json +++ b/apollo-router/tests/fixtures/type_conditions/artwork_disabled.json @@ -2,7 +2,7 @@ "mocks": [ { "request": { - "query":"query Search__artworkSubgraph__1($representations:[_Any!]!$movieResultParam:String){_entities(representations:$representations){...on EntityCollectionSection{title artwork(params:$movieResultParam)}...on GallerySection{artwork(params:$movieResultParam)}}}", + "query":"query Search__artworkSubgraph__1($representations:[_Any!]!$movieResultParam:String){_entities(representations:$representations){..._generated_onEntityCollectionSection2_0...on GallerySection{artwork(params:$movieResultParam)}}}fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection{title artwork(params:$movieResultParam)}", "operationName":"Search__artworkSubgraph__1", "variables":{ "representations":[ @@ -79,4 +79,4 @@ } } ] -} \ No newline at end of file +} diff --git a/apollo-router/tests/fixtures/type_conditions/search.json b/apollo-router/tests/fixtures/type_conditions/search.json index 1393fcfd02..85bc7facaa 100644 --- a/apollo-router/tests/fixtures/type_conditions/search.json +++ b/apollo-router/tests/fixtures/type_conditions/search.json @@ -2,7 +2,7 @@ "mocks": [ { "request": { - "query":"query Search__searchSubgraph__0{search{__typename ...on MovieResult{sections{__typename ...on EntityCollectionSection{__typename id}...on GallerySection{__typename id}}id}...on ArticleResult{id sections{__typename ...on GallerySection{__typename id}...on EntityCollectionSection{__typename id}}}}}", + "query":"query Search__searchSubgraph__0{search{__typename ..._generated_onMovieResult2_0 ..._generated_onArticleResult2_0}}fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection{__typename id}fragment _generated_onGallerySection2_0 on GallerySection{__typename id}fragment _generated_onMovieResult2_0 on MovieResult{sections{__typename ..._generated_onEntityCollectionSection2_0 ..._generated_onGallerySection2_0}id}fragment _generated_onArticleResult2_0 on ArticleResult{id sections{__typename ..._generated_onGallerySection2_0 ..._generated_onEntityCollectionSection2_0}}", "operationName":"Search__searchSubgraph__0" }, "response": { diff --git a/apollo-router/tests/fixtures/type_conditions/search_list_of_list.json b/apollo-router/tests/fixtures/type_conditions/search_list_of_list.json index 228e4ab0db..6197584e2b 100644 --- a/apollo-router/tests/fixtures/type_conditions/search_list_of_list.json +++ b/apollo-router/tests/fixtures/type_conditions/search_list_of_list.json @@ -2,7 +2,7 @@ "mocks": [ { "request": { - "query":"query Search__searchSubgraph__0{searchListOfList{__typename ...on MovieResult{sections{__typename ...on EntityCollectionSection{__typename id}...on GallerySection{__typename id}}id}...on ArticleResult{id sections{__typename ...on GallerySection{__typename id}...on EntityCollectionSection{__typename id}}}}}", + "query": "query Search__searchSubgraph__0 { searchListOfList { __typename ..._generated_onMovieResult2_0 ..._generated_onArticleResult2_0 } } fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection { __typename id } fragment _generated_onGallerySection2_0 on GallerySection { __typename id } fragment _generated_onMovieResult2_0 on MovieResult { sections { __typename ..._generated_onEntityCollectionSection2_0 ..._generated_onGallerySection2_0 } id } fragment _generated_onArticleResult2_0 on ArticleResult { id sections { __typename ..._generated_onGallerySection2_0 ..._generated_onEntityCollectionSection2_0 } }", "operationName":"Search__searchSubgraph__0" }, "response": { @@ -133,4 +133,4 @@ } } ] -} \ No newline at end of file +} diff --git a/apollo-router/tests/fixtures/type_conditions/search_list_of_list_of_list.json b/apollo-router/tests/fixtures/type_conditions/search_list_of_list_of_list.json index 1c2023c5ec..e183b3e65c 100644 --- a/apollo-router/tests/fixtures/type_conditions/search_list_of_list_of_list.json +++ b/apollo-router/tests/fixtures/type_conditions/search_list_of_list_of_list.json @@ -2,7 +2,7 @@ "mocks": [ { "request": { - "query":"query Search__searchSubgraph__0{searchListOfListOfList{__typename ...on MovieResult{sections{__typename ...on EntityCollectionSection{__typename id}...on GallerySection{__typename id}}id}...on ArticleResult{id sections{__typename ...on GallerySection{__typename id}...on EntityCollectionSection{__typename id}}}}}", + "query":"query Search__searchSubgraph__0 { searchListOfListOfList { __typename ..._generated_onMovieResult2_0 ..._generated_onArticleResult2_0 } } fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection { __typename id } fragment _generated_onGallerySection2_0 on GallerySection { __typename id } fragment _generated_onMovieResult2_0 on MovieResult { sections { __typename ..._generated_onEntityCollectionSection2_0 ..._generated_onGallerySection2_0 } id } fragment _generated_onArticleResult2_0 on ArticleResult { id sections { __typename ..._generated_onGallerySection2_0 ..._generated_onEntityCollectionSection2_0 } }", "operationName":"Search__searchSubgraph__0" }, "response": { @@ -137,4 +137,4 @@ } } ] -} \ No newline at end of file +} diff --git a/apollo-router/tests/integration/fixtures/query_planner_redis_config_update_query_fragments.router.yaml b/apollo-router/tests/integration/fixtures/query_planner_redis_config_update_query_fragments.router.yaml index ffb1e49152..e2232cb331 100644 --- a/apollo-router/tests/integration/fixtures/query_planner_redis_config_update_query_fragments.router.yaml +++ b/apollo-router/tests/integration/fixtures/query_planner_redis_config_update_query_fragments.router.yaml @@ -1,4 +1,4 @@ -# This config updates the query plan options so that we can see if there is a different redis cache entry generted for query plans +# This config updates the query plan options so that we can see if there is a different redis cache entry generated for query plans supergraph: query_planning: cache: @@ -7,5 +7,5 @@ supergraph: urls: - redis://localhost:6379 ttl: 10s - generate_query_fragments: true + generate_query_fragments: false diff --git a/apollo-router/tests/integration/redis.rs b/apollo-router/tests/integration/redis.rs index ff42bf8d7e..955cbc9290 100644 --- a/apollo-router/tests/integration/redis.rs +++ b/apollo-router/tests/integration/redis.rs @@ -51,7 +51,7 @@ async fn query_planner_cache() -> Result<(), BoxError> { } // If this test fails and the cache key format changed you'll need to update the key here. // Look at the top of the file for instructions on getting the new cache key. - let known_cache_key = "plan:cache:1:federation:v2.9.3:70f115ebba5991355c17f4f56ba25bb093c519c4db49a30f3b10de279a4e3fa4:opname:3973e022e93220f9212c18d0d0c543ae7c309e46640da93a4a0314de999f5112:metadata:0ade8e18db172d9d51b36a2112513c15032d103100644df418a50596de3adfba"; + let known_cache_key = "plan:cache:1:federation:v2.9.3:70f115ebba5991355c17f4f56ba25bb093c519c4db49a30f3b10de279a4e3fa4:opname:3973e022e93220f9212c18d0d0c543ae7c309e46640da93a4a0314de999f5112:metadata:1cfc840090ac76a98f8bd51442f41fd6ca4c8d918b3f8d87894170745acf0734"; let config = RedisConfig::from_url("redis://127.0.0.1:6379").unwrap(); let client = RedisClient::new(config, None, None, None); @@ -420,6 +420,10 @@ async fn entity_cache_basic() -> Result<(), BoxError> { }, "include_subgraph_errors": { "all": true + }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, } })) .unwrap() @@ -534,6 +538,10 @@ async fn entity_cache_basic() -> Result<(), BoxError> { }, "include_subgraph_errors": { "all": true + }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, } })) .unwrap() @@ -750,6 +758,10 @@ async fn entity_cache_authorization() -> Result<(), BoxError> { }, "include_subgraph_errors": { "all": true + }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, } })) .unwrap() @@ -962,8 +974,9 @@ async fn connection_failure_blocks_startup() { #[tokio::test(flavor = "multi_thread")] async fn query_planner_redis_update_query_fragments() { test_redis_query_plan_config_update( + // This configuration turns the fragment generation option *off*. include_str!("fixtures/query_planner_redis_config_update_query_fragments.router.yaml"), - "plan:cache:1:federation:v2.9.3:e15b4f5cd51b8cc728e3f5171611073455601e81196cd3cbafc5610d9769a370:opname:3973e022e93220f9212c18d0d0c543ae7c309e46640da93a4a0314de999f5112:metadata:1cfc840090ac76a98f8bd51442f41fd6ca4c8d918b3f8d87894170745acf0734", + "plan:cache:1:federation:v2.9.3:e15b4f5cd51b8cc728e3f5171611073455601e81196cd3cbafc5610d9769a370:opname:3973e022e93220f9212c18d0d0c543ae7c309e46640da93a4a0314de999f5112:metadata:0ade8e18db172d9d51b36a2112513c15032d103100644df418a50596de3adfba", ) .await; } @@ -993,7 +1006,7 @@ async fn query_planner_redis_update_defer() { // test just passes locally. test_redis_query_plan_config_update( include_str!("fixtures/query_planner_redis_config_update_defer.router.yaml"), - "plan:cache:1:federation:v2.9.3:e15b4f5cd51b8cc728e3f5171611073455601e81196cd3cbafc5610d9769a370:opname:3973e022e93220f9212c18d0d0c543ae7c309e46640da93a4a0314de999f5112:metadata:2f7fb939d2a8fc978e5a4e9d17998074fc30366dcc673236237a885819084fc0", + "plan:cache:1:federation:v2.9.3:e15b4f5cd51b8cc728e3f5171611073455601e81196cd3cbafc5610d9769a370:opname:3973e022e93220f9212c18d0d0c543ae7c309e46640da93a4a0314de999f5112:metadata:066f41523274aed2428e0f08c9de077ee748a1d8470ec31edb5224030a198f3b", ) .await; } @@ -1015,7 +1028,7 @@ async fn query_planner_redis_update_type_conditional_fetching() { include_str!( "fixtures/query_planner_redis_config_update_type_conditional_fetching.router.yaml" ), - "plan:cache:1:federation:v2.9.3:e15b4f5cd51b8cc728e3f5171611073455601e81196cd3cbafc5610d9769a370:opname:3973e022e93220f9212c18d0d0c543ae7c309e46640da93a4a0314de999f5112:metadata:0fd0a376f59f0565768ea5ad8eadfbbf60d64c593c807457a0776d2f39773a25", + "plan:cache:1:federation:v2.9.3:e15b4f5cd51b8cc728e3f5171611073455601e81196cd3cbafc5610d9769a370:opname:3973e022e93220f9212c18d0d0c543ae7c309e46640da93a4a0314de999f5112:metadata:b31d320db1af4015998cc89027f0ede2305dcc61724365e9b76d4252f90c7677", ) .await; } @@ -1037,7 +1050,7 @@ async fn query_planner_redis_update_reuse_query_fragments() { include_str!( "fixtures/query_planner_redis_config_update_reuse_query_fragments.router.yaml" ), - "plan:cache:1:federation:v2.9.3:e15b4f5cd51b8cc728e3f5171611073455601e81196cd3cbafc5610d9769a370:opname:3973e022e93220f9212c18d0d0c543ae7c309e46640da93a4a0314de999f5112:metadata:3f30f0e2d149d00c9370c8046e4dd5f23d6ceb6f05a6cf06d5eb021510564248", + "plan:cache:1:federation:v2.9.3:e15b4f5cd51b8cc728e3f5171611073455601e81196cd3cbafc5610d9769a370:opname:3973e022e93220f9212c18d0d0c543ae7c309e46640da93a4a0314de999f5112:metadata:d54414eeede3a1bf631d88a84a1e3a354683be87746e79a69769cf18d919cc01", ) .await; } @@ -1061,8 +1074,7 @@ async fn test_redis_query_plan_config_update(updated_config: &str, new_cache_key router.assert_started().await; router.clear_redis_cache().await; - // If the tests above are failing, this is the key that needs to be changed first. - let starting_key = "plan:cache:1:federation:v2.9.3:e15b4f5cd51b8cc728e3f5171611073455601e81196cd3cbafc5610d9769a370:opname:3973e022e93220f9212c18d0d0c543ae7c309e46640da93a4a0314de999f5112:metadata:0ade8e18db172d9d51b36a2112513c15032d103100644df418a50596de3adfba"; + let starting_key = "plan:cache:1:federation:v2.9.3:e15b4f5cd51b8cc728e3f5171611073455601e81196cd3cbafc5610d9769a370:opname:3973e022e93220f9212c18d0d0c543ae7c309e46640da93a4a0314de999f5112:metadata:1cfc840090ac76a98f8bd51442f41fd6ca4c8d918b3f8d87894170745acf0734"; assert_ne!(starting_key, new_cache_key, "starting_key (cache key for the initial config) and new_cache_key (cache key with the updated config) should not be equal. This either means that the cache key is not being generated correctly, or that the test is not actually checking the updated key."); router.execute_default_query().await; diff --git a/apollo-router/tests/samples/core/defer/plan.json b/apollo-router/tests/samples/core/defer/plan.json index b2499400bd..72dd5efed0 100644 --- a/apollo-router/tests/samples/core/defer/plan.json +++ b/apollo-router/tests/samples/core/defer/plan.json @@ -32,7 +32,7 @@ { "request": { "body": { - "query": "query($representations:[_Any!]!){_entities(representations:$representations){...on User{reviews{body}}}}", + "query": "query($representations:[_Any!]!){_entities(representations:$representations){..._generated_onUser1_0}}fragment _generated_onUser1_0 on User{reviews{body}}", "variables": { "representations": [ { @@ -103,4 +103,4 @@ "type": "Stop" } ] -} \ No newline at end of file +} diff --git a/apollo-router/tests/samples/enterprise/entity-cache/defer/plan.json b/apollo-router/tests/samples/enterprise/entity-cache/defer/plan.json index 265e282056..83a777d329 100644 --- a/apollo-router/tests/samples/enterprise/entity-cache/defer/plan.json +++ b/apollo-router/tests/samples/enterprise/entity-cache/defer/plan.json @@ -39,7 +39,7 @@ { "request": { "body": { - "query": "query CacheDefer__cache_defer_reviews__1($representations:[_Any!]!){_entities(representations:$representations){...on User{reviews{body}}}}", + "query": "query CacheDefer__cache_defer_reviews__1($representations:[_Any!]!){_entities(representations:$representations){..._generated_onUser1_0}}fragment _generated_onUser1_0 on User{reviews{body}}", "operationName": "CacheDefer__cache_defer_reviews__1", "variables": { "representations": [ @@ -110,4 +110,4 @@ "type": "Stop" } ] -} \ No newline at end of file +} diff --git a/apollo-router/tests/samples/enterprise/entity-cache/invalidation-entity-key/plan.json b/apollo-router/tests/samples/enterprise/entity-cache/invalidation-entity-key/plan.json index 1bb1bc0210..c8588ed2b7 100644 --- a/apollo-router/tests/samples/enterprise/entity-cache/invalidation-entity-key/plan.json +++ b/apollo-router/tests/samples/enterprise/entity-cache/invalidation-entity-key/plan.json @@ -31,7 +31,7 @@ { "request": { "body": { - "query":"query InvalidationEntityKey__invalidation_entity_key_reviews__1($representations:[_Any!]!){_entities(representations:$representations){...on Product{reviews{body}}}}", + "query":"query InvalidationEntityKey__invalidation_entity_key_reviews__1($representations:[_Any!]!){_entities(representations:$representations){..._generated_onProduct1_0}}fragment _generated_onProduct1_0 on Product{reviews{body}}", "operationName": "InvalidationEntityKey__invalidation_entity_key_reviews__1", "variables":{"representations":[{"upc":"0","__typename":"Product"},{"upc":"1","__typename":"Product"}]} } @@ -115,7 +115,7 @@ { "request": { "body": { - "query":"query InvalidationEntityKey__invalidation_entity_key_reviews__1($representations:[_Any!]!){_entities(representations:$representations){...on Product{reviews{body}}}}", + "query":"query InvalidationEntityKey__invalidation_entity_key_reviews__1($representations:[_Any!]!){_entities(representations:$representations){..._generated_onProduct1_0}}fragment _generated_onProduct1_0 on Product{reviews{body}}", "variables":{"representations":[{"upc":"1","__typename":"Product"}]} } }, @@ -202,7 +202,7 @@ { "request": { "body": { - "query":"query InvalidationEntityKey__invalidation_entity_key_reviews__1($representations:[_Any!]!){_entities(representations:$representations){...on Product{reviews{body}}}}", + "query":"query InvalidationEntityKey__invalidation_entity_key_reviews__1($representations:[_Any!]!){_entities(representations:$representations){..._generated_onProduct1_0}}fragment _generated_onProduct1_0 on Product{reviews{body}}", "variables":{"representations":[{"upc":"1","__typename":"Product"}]} } }, @@ -250,4 +250,4 @@ "type": "Stop" } ] -} \ No newline at end of file +} diff --git a/apollo-router/tests/set_context.rs b/apollo-router/tests/set_context.rs index 47d8deb076..aae8107137 100644 --- a/apollo-router/tests/set_context.rs +++ b/apollo-router/tests/set_context.rs @@ -42,6 +42,10 @@ async fn run_single_request(query: &str, mocks: &[(&'static str, &'static str)]) }, "include_subgraph_errors": { "all": true + }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, } }}, mocks, diff --git a/apollo-router/tests/snapshots/type_conditions___test_type_conditions_disabled-2.snap b/apollo-router/tests/snapshots/type_conditions___test_type_conditions_disabled-2.snap index 17f0ec285c..390a7c79df 100644 --- a/apollo-router/tests/snapshots/type_conditions___test_type_conditions_disabled-2.snap +++ b/apollo-router/tests/snapshots/type_conditions___test_type_conditions_disabled-2.snap @@ -72,14 +72,14 @@ expression: response "kind": "Fetch", "serviceName": "searchSubgraph", "variableUsages": [], - "operation": "query Search__searchSubgraph__0 { search { __typename ... on MovieResult { sections { __typename ... on EntityCollectionSection { __typename id } ... on GallerySection { __typename id } } id } ... on ArticleResult { id sections { __typename ... on GallerySection { __typename id } ... on EntityCollectionSection { __typename id } } } } }", + "operation": "query Search__searchSubgraph__0 { search { __typename ..._generated_onMovieResult2_0 ..._generated_onArticleResult2_0 } } fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection { __typename id } fragment _generated_onGallerySection2_0 on GallerySection { __typename id } fragment _generated_onMovieResult2_0 on MovieResult { sections { __typename ..._generated_onEntityCollectionSection2_0 ..._generated_onGallerySection2_0 } id } fragment _generated_onArticleResult2_0 on ArticleResult { id sections { __typename ..._generated_onGallerySection2_0 ..._generated_onEntityCollectionSection2_0 } }", "operationName": "Search__searchSubgraph__0", "operationKind": "query", "id": null, "inputRewrites": null, "outputRewrites": null, "contextRewrites": null, - "schemaAwareHash": "587c887350ef75eaf4b647be94fd682616bcd33909e15fb797cee226e95fa36a", + "schemaAwareHash": "70ca85b28e861b24a7749862930a5f965c4c6e8074d60a87a3952d596fe7cc36", "authorization": { "is_authenticated": false, "scopes": [], @@ -130,14 +130,14 @@ expression: response "variableUsages": [ "movieResultParam" ], - "operation": "query Search__artworkSubgraph__1($representations: [_Any!]!, $movieResultParam: String) { _entities(representations: $representations) { ... on EntityCollectionSection { title artwork(params: $movieResultParam) } ... on GallerySection { artwork(params: $movieResultParam) } } }", + "operation": "query Search__artworkSubgraph__1($representations: [_Any!]!, $movieResultParam: String) { _entities(representations: $representations) { ..._generated_onEntityCollectionSection2_0 ... on GallerySection { artwork(params: $movieResultParam) } } } fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection { title artwork(params: $movieResultParam) }", "operationName": "Search__artworkSubgraph__1", "operationKind": "query", "id": null, "inputRewrites": null, "outputRewrites": null, "contextRewrites": null, - "schemaAwareHash": "622eb49d4e52ff2636348e103f941d04b783fec97de59d0ae6635d9272f97ad8", + "schemaAwareHash": "317a722a677563080aeac92f60ac2257d9288ca6851a0e8980fcf18f58b462a8", "authorization": { "is_authenticated": false, "scopes": [], @@ -148,7 +148,7 @@ expression: response ] } }, - "text": "QueryPlan {\n Sequence {\n Fetch(service: \"searchSubgraph\") {\n {\n search {\n __typename\n ... on MovieResult {\n sections {\n __typename\n ... on EntityCollectionSection {\n __typename\n id\n }\n ... on GallerySection {\n __typename\n id\n }\n }\n id\n }\n ... on ArticleResult {\n id\n sections {\n __typename\n ... on GallerySection {\n __typename\n id\n }\n ... on EntityCollectionSection {\n __typename\n id\n }\n }\n }\n }\n }\n },\n Flatten(path: \"search.@.sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on EntityCollectionSection {\n __typename\n id\n }\n ... on GallerySection {\n __typename\n id\n }\n } =>\n {\n ... on EntityCollectionSection {\n title\n artwork(params: $movieResultParam)\n }\n ... on GallerySection {\n artwork(params: $movieResultParam)\n }\n }\n },\n },\n },\n}" + "text": "QueryPlan {\n Sequence {\n Fetch(service: \"searchSubgraph\") {\n {\n search {\n __typename\n ..._generated_onMovieResult2_0\n ..._generated_onArticleResult2_0\n }\n }\n\n fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection {\n __typename\n id\n }\n\n fragment _generated_onGallerySection2_0 on GallerySection {\n __typename\n id\n }\n\n fragment _generated_onMovieResult2_0 on MovieResult {\n sections {\n __typename\n ..._generated_onEntityCollectionSection2_0\n ..._generated_onGallerySection2_0\n }\n id\n }\n\n fragment _generated_onArticleResult2_0 on ArticleResult {\n id\n sections {\n __typename\n ..._generated_onGallerySection2_0\n ..._generated_onEntityCollectionSection2_0\n }\n }\n },\n Flatten(path: \"search.@.sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on EntityCollectionSection {\n __typename\n id\n }\n ... on GallerySection {\n __typename\n id\n }\n } =>\n {\n ..._generated_onEntityCollectionSection2_0\n ... on GallerySection {\n artwork(params: $movieResultParam)\n }\n }\n\n fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection {\n title\n artwork(params: $movieResultParam)\n }\n },\n },\n },\n}" } } } diff --git a/apollo-router/tests/snapshots/type_conditions___test_type_conditions_disabled.snap b/apollo-router/tests/snapshots/type_conditions___test_type_conditions_disabled.snap index f355685192..687028717f 100644 --- a/apollo-router/tests/snapshots/type_conditions___test_type_conditions_disabled.snap +++ b/apollo-router/tests/snapshots/type_conditions___test_type_conditions_disabled.snap @@ -72,14 +72,14 @@ expression: response "kind": "Fetch", "serviceName": "searchSubgraph", "variableUsages": [], - "operation": "query Search__searchSubgraph__0 { search { __typename ... on MovieResult { sections { __typename ... on EntityCollectionSection { __typename id } ... on GallerySection { __typename id } } id } ... on ArticleResult { id sections { __typename ... on GallerySection { __typename id } ... on EntityCollectionSection { __typename id } } } } }", + "operation": "query Search__searchSubgraph__0 { search { __typename ..._generated_onMovieResult2_0 ..._generated_onArticleResult2_0 } } fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection { __typename id } fragment _generated_onGallerySection2_0 on GallerySection { __typename id } fragment _generated_onMovieResult2_0 on MovieResult { sections { __typename ..._generated_onEntityCollectionSection2_0 ..._generated_onGallerySection2_0 } id } fragment _generated_onArticleResult2_0 on ArticleResult { id sections { __typename ..._generated_onGallerySection2_0 ..._generated_onEntityCollectionSection2_0 } }", "operationName": "Search__searchSubgraph__0", "operationKind": "query", "id": null, "inputRewrites": null, "outputRewrites": null, "contextRewrites": null, - "schemaAwareHash": "5201830580c9c5fadd9c59aea072878f84465c1ae9d905207fa281aa7c1d5340", + "schemaAwareHash": "0e1644746fe4beab7def35ec8cc12bde39874c6bb8b9dfd928456196b814a111", "authorization": { "is_authenticated": false, "scopes": [], @@ -130,14 +130,14 @@ expression: response "variableUsages": [ "movieResultParam" ], - "operation": "query Search__artworkSubgraph__1($representations: [_Any!]!, $movieResultParam: String) { _entities(representations: $representations) { ... on EntityCollectionSection { title artwork(params: $movieResultParam) } ... on GallerySection { artwork(params: $movieResultParam) } } }", + "operation": "query Search__artworkSubgraph__1($representations: [_Any!]!, $movieResultParam: String) { _entities(representations: $representations) { ..._generated_onEntityCollectionSection2_0 ... on GallerySection { artwork(params: $movieResultParam) } } } fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection { title artwork(params: $movieResultParam) }", "operationName": "Search__artworkSubgraph__1", "operationKind": "query", "id": null, "inputRewrites": null, "outputRewrites": null, "contextRewrites": null, - "schemaAwareHash": "62ff891f6971184d3e42b98f8166be72027b5479f9ec098af460a48ea6f6cbf4", + "schemaAwareHash": "6510f6b9672829bd9217618b78ef6f329fbddb125f88184d04e6faaa982ff8bb", "authorization": { "is_authenticated": false, "scopes": [], @@ -148,7 +148,7 @@ expression: response ] } }, - "text": "QueryPlan {\n Sequence {\n Fetch(service: \"searchSubgraph\") {\n {\n search {\n __typename\n ... on MovieResult {\n sections {\n __typename\n ... on EntityCollectionSection {\n __typename\n id\n }\n ... on GallerySection {\n __typename\n id\n }\n }\n id\n }\n ... on ArticleResult {\n id\n sections {\n __typename\n ... on GallerySection {\n __typename\n id\n }\n ... on EntityCollectionSection {\n __typename\n id\n }\n }\n }\n }\n }\n },\n Flatten(path: \"search.@.sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on EntityCollectionSection {\n __typename\n id\n }\n ... on GallerySection {\n __typename\n id\n }\n } =>\n {\n ... on EntityCollectionSection {\n title\n artwork(params: $movieResultParam)\n }\n ... on GallerySection {\n artwork(params: $movieResultParam)\n }\n }\n },\n },\n },\n}" + "text": "QueryPlan {\n Sequence {\n Fetch(service: \"searchSubgraph\") {\n {\n search {\n __typename\n ..._generated_onMovieResult2_0\n ..._generated_onArticleResult2_0\n }\n }\n \n fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection {\n __typename\n id\n }\n \n fragment _generated_onGallerySection2_0 on GallerySection {\n __typename\n id\n }\n \n fragment _generated_onMovieResult2_0 on MovieResult {\n sections {\n __typename\n ..._generated_onEntityCollectionSection2_0\n ..._generated_onGallerySection2_0\n }\n id\n }\n \n fragment _generated_onArticleResult2_0 on ArticleResult {\n id\n sections {\n __typename\n ..._generated_onGallerySection2_0\n ..._generated_onEntityCollectionSection2_0\n }\n }\n },\n Flatten(path: \"search.@.sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on EntityCollectionSection {\n __typename\n id\n }\n ... on GallerySection {\n __typename\n id\n }\n } =>\n {\n ..._generated_onEntityCollectionSection2_0\n ... on GallerySection {\n artwork(params: $movieResultParam)\n }\n }\n \n fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection {\n title\n artwork(params: $movieResultParam)\n }\n },\n },\n },\n}" } } } diff --git a/apollo-router/tests/snapshots/type_conditions___test_type_conditions_enabled-2.snap b/apollo-router/tests/snapshots/type_conditions___test_type_conditions_enabled-2.snap index 01e49a0721..ed94ed7a85 100644 --- a/apollo-router/tests/snapshots/type_conditions___test_type_conditions_enabled-2.snap +++ b/apollo-router/tests/snapshots/type_conditions___test_type_conditions_enabled-2.snap @@ -72,14 +72,14 @@ expression: response "kind": "Fetch", "serviceName": "searchSubgraph", "variableUsages": [], - "operation": "query Search__searchSubgraph__0 { search { __typename ... on MovieResult { sections { __typename ... on EntityCollectionSection { __typename id } ... on GallerySection { __typename id } } id } ... on ArticleResult { id sections { __typename ... on GallerySection { __typename id } ... on EntityCollectionSection { __typename id } } } } }", + "operation": "query Search__searchSubgraph__0 { search { __typename ..._generated_onMovieResult2_0 ..._generated_onArticleResult2_0 } } fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection { __typename id } fragment _generated_onGallerySection2_0 on GallerySection { __typename id } fragment _generated_onMovieResult2_0 on MovieResult { sections { __typename ..._generated_onEntityCollectionSection2_0 ..._generated_onGallerySection2_0 } id } fragment _generated_onArticleResult2_0 on ArticleResult { id sections { __typename ..._generated_onGallerySection2_0 ..._generated_onEntityCollectionSection2_0 } }", "operationName": "Search__searchSubgraph__0", "operationKind": "query", "id": null, "inputRewrites": null, "outputRewrites": null, "contextRewrites": null, - "schemaAwareHash": "587c887350ef75eaf4b647be94fd682616bcd33909e15fb797cee226e95fa36a", + "schemaAwareHash": "70ca85b28e861b24a7749862930a5f965c4c6e8074d60a87a3952d596fe7cc36", "authorization": { "is_authenticated": false, "scopes": [], @@ -133,14 +133,14 @@ expression: response "variableUsages": [ "articleResultParam" ], - "operation": "query Search__artworkSubgraph__1($representations: [_Any!]!, $articleResultParam: String) { _entities(representations: $representations) { ... on GallerySection { artwork(params: $articleResultParam) } ... on EntityCollectionSection { artwork(params: $articleResultParam) title } } }", + "operation": "query Search__artworkSubgraph__1($representations: [_Any!]!, $articleResultParam: String) { _entities(representations: $representations) { ... on GallerySection { artwork(params: $articleResultParam) } ..._generated_onEntityCollectionSection2_0 } } fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection { artwork(params: $articleResultParam) title }", "operationName": "Search__artworkSubgraph__1", "operationKind": "query", "id": null, "inputRewrites": null, "outputRewrites": null, "contextRewrites": null, - "schemaAwareHash": "a0bf36d3a611df53c3a60b9b124a2887f2d266858221c606ace0985d101d64bd", + "schemaAwareHash": "1d21a65a3b5a31e17f7834750ef5b37fb49d99d0a1e2145f00a62d43c5f8423a", "authorization": { "is_authenticated": false, "scopes": [], @@ -192,14 +192,14 @@ expression: response "variableUsages": [ "movieResultParam" ], - "operation": "query Search__artworkSubgraph__2($representations: [_Any!]!, $movieResultParam: String) { _entities(representations: $representations) { ... on EntityCollectionSection { title artwork(params: $movieResultParam) } ... on GallerySection { artwork(params: $movieResultParam) } } }", + "operation": "query Search__artworkSubgraph__2($representations: [_Any!]!, $movieResultParam: String) { _entities(representations: $representations) { ..._generated_onEntityCollectionSection2_0 ... on GallerySection { artwork(params: $movieResultParam) } } } fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection { title artwork(params: $movieResultParam) }", "operationName": "Search__artworkSubgraph__2", "operationKind": "query", "id": null, "inputRewrites": null, "outputRewrites": null, "contextRewrites": null, - "schemaAwareHash": "3e84a53f967bf40d4c08254a94f3fa32a828ab3ad8184a22bb3439c596ecaaf4", + "schemaAwareHash": "df321f6532c2c9eda0d8c042e5f08073c24e558dd0cae01054886b79416a6c08", "authorization": { "is_authenticated": false, "scopes": [], @@ -212,7 +212,7 @@ expression: response ] } }, - "text": "QueryPlan {\n Sequence {\n Fetch(service: \"searchSubgraph\") {\n {\n search {\n __typename\n ... on MovieResult {\n sections {\n __typename\n ... on EntityCollectionSection {\n __typename\n id\n }\n ... on GallerySection {\n __typename\n id\n }\n }\n id\n }\n ... on ArticleResult {\n id\n sections {\n __typename\n ... on GallerySection {\n __typename\n id\n }\n ... on EntityCollectionSection {\n __typename\n id\n }\n }\n }\n }\n }\n },\n Parallel {\n Flatten(path: \"search.@|[ArticleResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on GallerySection {\n __typename\n id\n }\n ... on EntityCollectionSection {\n __typename\n id\n }\n } =>\n {\n ... on GallerySection {\n artwork(params: $articleResultParam)\n }\n ... on EntityCollectionSection {\n artwork(params: $articleResultParam)\n title\n }\n }\n },\n },\n Flatten(path: \"search.@|[MovieResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on EntityCollectionSection {\n __typename\n id\n }\n ... on GallerySection {\n __typename\n id\n }\n } =>\n {\n ... on EntityCollectionSection {\n title\n artwork(params: $movieResultParam)\n }\n ... on GallerySection {\n artwork(params: $movieResultParam)\n }\n }\n },\n },\n },\n },\n}" + "text": "QueryPlan {\n Sequence {\n Fetch(service: \"searchSubgraph\") {\n {\n search {\n __typename\n ..._generated_onMovieResult2_0\n ..._generated_onArticleResult2_0\n }\n }\n\n fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection {\n __typename\n id\n }\n\n fragment _generated_onGallerySection2_0 on GallerySection {\n __typename\n id\n }\n\n fragment _generated_onMovieResult2_0 on MovieResult {\n sections {\n __typename\n ..._generated_onEntityCollectionSection2_0\n ..._generated_onGallerySection2_0\n }\n id\n }\n\n fragment _generated_onArticleResult2_0 on ArticleResult {\n id\n sections {\n __typename\n ..._generated_onGallerySection2_0\n ..._generated_onEntityCollectionSection2_0\n }\n }\n },\n Parallel {\n Flatten(path: \"search.@|[ArticleResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on GallerySection {\n __typename\n id\n }\n ... on EntityCollectionSection {\n __typename\n id\n }\n } =>\n {\n ... on GallerySection {\n artwork(params: $articleResultParam)\n }\n ..._generated_onEntityCollectionSection2_0\n }\n\n fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection {\n artwork(params: $articleResultParam)\n title\n }\n },\n },\n Flatten(path: \"search.@|[MovieResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on EntityCollectionSection {\n __typename\n id\n }\n ... on GallerySection {\n __typename\n id\n }\n } =>\n {\n ..._generated_onEntityCollectionSection2_0\n ... on GallerySection {\n artwork(params: $movieResultParam)\n }\n }\n\n fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection {\n title\n artwork(params: $movieResultParam)\n }\n },\n },\n },\n },\n}" } } } diff --git a/apollo-router/tests/snapshots/type_conditions___test_type_conditions_enabled.snap b/apollo-router/tests/snapshots/type_conditions___test_type_conditions_enabled.snap index a8afd1fa0e..08a9782c85 100644 --- a/apollo-router/tests/snapshots/type_conditions___test_type_conditions_enabled.snap +++ b/apollo-router/tests/snapshots/type_conditions___test_type_conditions_enabled.snap @@ -72,14 +72,14 @@ expression: response "kind": "Fetch", "serviceName": "searchSubgraph", "variableUsages": [], - "operation": "query Search__searchSubgraph__0 { search { __typename ... on MovieResult { sections { __typename ... on EntityCollectionSection { __typename id } ... on GallerySection { __typename id } } id } ... on ArticleResult { id sections { __typename ... on GallerySection { __typename id } ... on EntityCollectionSection { __typename id } } } } }", + "operation": "query Search__searchSubgraph__0 { search { __typename ..._generated_onMovieResult2_0 ..._generated_onArticleResult2_0 } } fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection { __typename id } fragment _generated_onGallerySection2_0 on GallerySection { __typename id } fragment _generated_onMovieResult2_0 on MovieResult { sections { __typename ..._generated_onEntityCollectionSection2_0 ..._generated_onGallerySection2_0 } id } fragment _generated_onArticleResult2_0 on ArticleResult { id sections { __typename ..._generated_onGallerySection2_0 ..._generated_onEntityCollectionSection2_0 } }", "operationName": "Search__searchSubgraph__0", "operationKind": "query", "id": null, "inputRewrites": null, "outputRewrites": null, "contextRewrites": null, - "schemaAwareHash": "5201830580c9c5fadd9c59aea072878f84465c1ae9d905207fa281aa7c1d5340", + "schemaAwareHash": "0e1644746fe4beab7def35ec8cc12bde39874c6bb8b9dfd928456196b814a111", "authorization": { "is_authenticated": false, "scopes": [], @@ -134,14 +134,14 @@ expression: response "variableUsages": [ "movieResultParam" ], - "operation": "query Search__artworkSubgraph__1($representations: [_Any!]!, $movieResultParam: String) { _entities(representations: $representations) { ... on EntityCollectionSection { title artwork(params: $movieResultParam) } ... on GallerySection { artwork(params: $movieResultParam) } } }", + "operation": "query Search__artworkSubgraph__1($representations: [_Any!]!, $movieResultParam: String) { _entities(representations: $representations) { ..._generated_onEntityCollectionSection2_0 ... on GallerySection { artwork(params: $movieResultParam) } } } fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection { title artwork(params: $movieResultParam) }", "operationName": "Search__artworkSubgraph__1", "operationKind": "query", "id": null, "inputRewrites": null, "outputRewrites": null, "contextRewrites": null, - "schemaAwareHash": "62ff891f6971184d3e42b98f8166be72027b5479f9ec098af460a48ea6f6cbf4", + "schemaAwareHash": "6510f6b9672829bd9217618b78ef6f329fbddb125f88184d04e6faaa982ff8bb", "authorization": { "is_authenticated": false, "scopes": [], @@ -194,14 +194,14 @@ expression: response "variableUsages": [ "articleResultParam" ], - "operation": "query Search__artworkSubgraph__2($representations: [_Any!]!, $articleResultParam: String) { _entities(representations: $representations) { ... on GallerySection { artwork(params: $articleResultParam) } ... on EntityCollectionSection { artwork(params: $articleResultParam) title } } }", + "operation": "query Search__artworkSubgraph__2($representations: [_Any!]!, $articleResultParam: String) { _entities(representations: $representations) { ... on GallerySection { artwork(params: $articleResultParam) } ..._generated_onEntityCollectionSection2_0 } } fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection { artwork(params: $articleResultParam) title }", "operationName": "Search__artworkSubgraph__2", "operationKind": "query", "id": null, "inputRewrites": null, "outputRewrites": null, "contextRewrites": null, - "schemaAwareHash": "7e6f6850777335eb1421a30a45f6888bb9e5d0acf8f55d576d55d1c4b7d23ec7", + "schemaAwareHash": "6bc34c108f7cf81896971bffad76dc5275d46231b4dfe492ccc205dda9a4aa16", "authorization": { "is_authenticated": false, "scopes": [], @@ -214,7 +214,7 @@ expression: response ] } }, - "text": "QueryPlan {\n Sequence {\n Fetch(service: \"searchSubgraph\") {\n {\n search {\n __typename\n ... on MovieResult {\n sections {\n __typename\n ... on EntityCollectionSection {\n __typename\n id\n }\n ... on GallerySection {\n __typename\n id\n }\n }\n id\n }\n ... on ArticleResult {\n id\n sections {\n __typename\n ... on GallerySection {\n __typename\n id\n }\n ... on EntityCollectionSection {\n __typename\n id\n }\n }\n }\n }\n }\n },\n Parallel {\n Flatten(path: \".search.@|[MovieResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on EntityCollectionSection {\n __typename\n id\n }\n ... on GallerySection {\n __typename\n id\n }\n } =>\n {\n ... on EntityCollectionSection {\n title\n artwork(params: $movieResultParam)\n }\n ... on GallerySection {\n artwork(params: $movieResultParam)\n }\n }\n },\n },\n Flatten(path: \".search.@|[ArticleResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on GallerySection {\n __typename\n id\n }\n ... on EntityCollectionSection {\n __typename\n id\n }\n } =>\n {\n ... on GallerySection {\n artwork(params: $articleResultParam)\n }\n ... on EntityCollectionSection {\n artwork(params: $articleResultParam)\n title\n }\n }\n },\n },\n },\n },\n}" + "text": "QueryPlan {\n Sequence {\n Fetch(service: \"searchSubgraph\") {\n {\n search {\n __typename\n ..._generated_onMovieResult2_0\n ..._generated_onArticleResult2_0\n }\n }\n \n fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection {\n __typename\n id\n }\n \n fragment _generated_onGallerySection2_0 on GallerySection {\n __typename\n id\n }\n \n fragment _generated_onMovieResult2_0 on MovieResult {\n sections {\n __typename\n ..._generated_onEntityCollectionSection2_0\n ..._generated_onGallerySection2_0\n }\n id\n }\n \n fragment _generated_onArticleResult2_0 on ArticleResult {\n id\n sections {\n __typename\n ..._generated_onGallerySection2_0\n ..._generated_onEntityCollectionSection2_0\n }\n }\n },\n Parallel {\n Flatten(path: \".search.@|[MovieResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on EntityCollectionSection {\n __typename\n id\n }\n ... on GallerySection {\n __typename\n id\n }\n } =>\n {\n ..._generated_onEntityCollectionSection2_0\n ... on GallerySection {\n artwork(params: $movieResultParam)\n }\n }\n \n fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection {\n title\n artwork(params: $movieResultParam)\n }\n },\n },\n Flatten(path: \".search.@|[ArticleResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on GallerySection {\n __typename\n id\n }\n ... on EntityCollectionSection {\n __typename\n id\n }\n } =>\n {\n ... on GallerySection {\n artwork(params: $articleResultParam)\n }\n ..._generated_onEntityCollectionSection2_0\n }\n \n fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection {\n artwork(params: $articleResultParam)\n title\n }\n },\n },\n },\n },\n}" } } } diff --git a/apollo-router/tests/snapshots/type_conditions___test_type_conditions_enabled_list_of_list-2.snap b/apollo-router/tests/snapshots/type_conditions___test_type_conditions_enabled_list_of_list-2.snap index c990725153..fc5007829d 100644 --- a/apollo-router/tests/snapshots/type_conditions___test_type_conditions_enabled_list_of_list-2.snap +++ b/apollo-router/tests/snapshots/type_conditions___test_type_conditions_enabled_list_of_list-2.snap @@ -134,14 +134,14 @@ expression: response "kind": "Fetch", "serviceName": "searchSubgraph", "variableUsages": [], - "operation": "query Search__searchSubgraph__0 { searchListOfList { __typename ... on MovieResult { sections { __typename ... on EntityCollectionSection { __typename id } ... on GallerySection { __typename id } } id } ... on ArticleResult { id sections { __typename ... on GallerySection { __typename id } ... on EntityCollectionSection { __typename id } } } } }", + "operation": "query Search__searchSubgraph__0 { searchListOfList { __typename ..._generated_onMovieResult2_0 ..._generated_onArticleResult2_0 } } fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection { __typename id } fragment _generated_onGallerySection2_0 on GallerySection { __typename id } fragment _generated_onMovieResult2_0 on MovieResult { sections { __typename ..._generated_onEntityCollectionSection2_0 ..._generated_onGallerySection2_0 } id } fragment _generated_onArticleResult2_0 on ArticleResult { id sections { __typename ..._generated_onGallerySection2_0 ..._generated_onEntityCollectionSection2_0 } }", "operationName": "Search__searchSubgraph__0", "operationKind": "query", "id": null, "inputRewrites": null, "outputRewrites": null, "contextRewrites": null, - "schemaAwareHash": "365685f6b9f1c5dd02506b27f50d63486f1ca6b5ced7b0253fc050ef73732e03", + "schemaAwareHash": "ff18ff586aee784ec507117854cb4b64f9693d528df1ee69c922b5d75ae637fb", "authorization": { "is_authenticated": false, "scopes": [], @@ -196,14 +196,14 @@ expression: response "variableUsages": [ "articleResultParam" ], - "operation": "query Search__artworkSubgraph__1($representations: [_Any!]!, $articleResultParam: String) { _entities(representations: $representations) { ... on GallerySection { artwork(params: $articleResultParam) } ... on EntityCollectionSection { artwork(params: $articleResultParam) title } } }", + "operation": "query Search__artworkSubgraph__1($representations: [_Any!]!, $articleResultParam: String) { _entities(representations: $representations) { ... on GallerySection { artwork(params: $articleResultParam) } ..._generated_onEntityCollectionSection2_0 } } fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection { artwork(params: $articleResultParam) title }", "operationName": "Search__artworkSubgraph__1", "operationKind": "query", "id": null, "inputRewrites": null, "outputRewrites": null, "contextRewrites": null, - "schemaAwareHash": "a0bf36d3a611df53c3a60b9b124a2887f2d266858221c606ace0985d101d64bd", + "schemaAwareHash": "1d21a65a3b5a31e17f7834750ef5b37fb49d99d0a1e2145f00a62d43c5f8423a", "authorization": { "is_authenticated": false, "scopes": [], @@ -256,14 +256,14 @@ expression: response "variableUsages": [ "movieResultParam" ], - "operation": "query Search__artworkSubgraph__2($representations: [_Any!]!, $movieResultParam: String) { _entities(representations: $representations) { ... on EntityCollectionSection { title artwork(params: $movieResultParam) } ... on GallerySection { artwork(params: $movieResultParam) } } }", + "operation": "query Search__artworkSubgraph__2($representations: [_Any!]!, $movieResultParam: String) { _entities(representations: $representations) { ..._generated_onEntityCollectionSection2_0 ... on GallerySection { artwork(params: $movieResultParam) } } } fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection { title artwork(params: $movieResultParam) }", "operationName": "Search__artworkSubgraph__2", "operationKind": "query", "id": null, "inputRewrites": null, "outputRewrites": null, "contextRewrites": null, - "schemaAwareHash": "3e84a53f967bf40d4c08254a94f3fa32a828ab3ad8184a22bb3439c596ecaaf4", + "schemaAwareHash": "df321f6532c2c9eda0d8c042e5f08073c24e558dd0cae01054886b79416a6c08", "authorization": { "is_authenticated": false, "scopes": [], @@ -276,7 +276,7 @@ expression: response ] } }, - "text": "QueryPlan {\n Sequence {\n Fetch(service: \"searchSubgraph\") {\n {\n searchListOfList {\n __typename\n ... on MovieResult {\n sections {\n __typename\n ... on EntityCollectionSection {\n __typename\n id\n }\n ... on GallerySection {\n __typename\n id\n }\n }\n id\n }\n ... on ArticleResult {\n id\n sections {\n __typename\n ... on GallerySection {\n __typename\n id\n }\n ... on EntityCollectionSection {\n __typename\n id\n }\n }\n }\n }\n }\n },\n Parallel {\n Flatten(path: \"searchListOfList.@.@|[ArticleResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on GallerySection {\n __typename\n id\n }\n ... on EntityCollectionSection {\n __typename\n id\n }\n } =>\n {\n ... on GallerySection {\n artwork(params: $articleResultParam)\n }\n ... on EntityCollectionSection {\n artwork(params: $articleResultParam)\n title\n }\n }\n },\n },\n Flatten(path: \"searchListOfList.@.@|[MovieResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on EntityCollectionSection {\n __typename\n id\n }\n ... on GallerySection {\n __typename\n id\n }\n } =>\n {\n ... on EntityCollectionSection {\n title\n artwork(params: $movieResultParam)\n }\n ... on GallerySection {\n artwork(params: $movieResultParam)\n }\n }\n },\n },\n },\n },\n}" + "text": "QueryPlan {\n Sequence {\n Fetch(service: \"searchSubgraph\") {\n {\n searchListOfList {\n __typename\n ..._generated_onMovieResult2_0\n ..._generated_onArticleResult2_0\n }\n }\n\n fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection {\n __typename\n id\n }\n\n fragment _generated_onGallerySection2_0 on GallerySection {\n __typename\n id\n }\n\n fragment _generated_onMovieResult2_0 on MovieResult {\n sections {\n __typename\n ..._generated_onEntityCollectionSection2_0\n ..._generated_onGallerySection2_0\n }\n id\n }\n\n fragment _generated_onArticleResult2_0 on ArticleResult {\n id\n sections {\n __typename\n ..._generated_onGallerySection2_0\n ..._generated_onEntityCollectionSection2_0\n }\n }\n },\n Parallel {\n Flatten(path: \"searchListOfList.@.@|[ArticleResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on GallerySection {\n __typename\n id\n }\n ... on EntityCollectionSection {\n __typename\n id\n }\n } =>\n {\n ... on GallerySection {\n artwork(params: $articleResultParam)\n }\n ..._generated_onEntityCollectionSection2_0\n }\n\n fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection {\n artwork(params: $articleResultParam)\n title\n }\n },\n },\n Flatten(path: \"searchListOfList.@.@|[MovieResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on EntityCollectionSection {\n __typename\n id\n }\n ... on GallerySection {\n __typename\n id\n }\n } =>\n {\n ..._generated_onEntityCollectionSection2_0\n ... on GallerySection {\n artwork(params: $movieResultParam)\n }\n }\n\n fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection {\n title\n artwork(params: $movieResultParam)\n }\n },\n },\n },\n },\n}" } } } diff --git a/apollo-router/tests/snapshots/type_conditions___test_type_conditions_enabled_list_of_list.snap b/apollo-router/tests/snapshots/type_conditions___test_type_conditions_enabled_list_of_list.snap index adf981893a..4c219874d6 100644 --- a/apollo-router/tests/snapshots/type_conditions___test_type_conditions_enabled_list_of_list.snap +++ b/apollo-router/tests/snapshots/type_conditions___test_type_conditions_enabled_list_of_list.snap @@ -134,14 +134,14 @@ expression: response "kind": "Fetch", "serviceName": "searchSubgraph", "variableUsages": [], - "operation": "query Search__searchSubgraph__0 { searchListOfList { __typename ... on MovieResult { sections { __typename ... on EntityCollectionSection { __typename id } ... on GallerySection { __typename id } } id } ... on ArticleResult { id sections { __typename ... on GallerySection { __typename id } ... on EntityCollectionSection { __typename id } } } } }", + "operation": "query Search__searchSubgraph__0 { searchListOfList { __typename ..._generated_onMovieResult2_0 ..._generated_onArticleResult2_0 } } fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection { __typename id } fragment _generated_onGallerySection2_0 on GallerySection { __typename id } fragment _generated_onMovieResult2_0 on MovieResult { sections { __typename ..._generated_onEntityCollectionSection2_0 ..._generated_onGallerySection2_0 } id } fragment _generated_onArticleResult2_0 on ArticleResult { id sections { __typename ..._generated_onGallerySection2_0 ..._generated_onEntityCollectionSection2_0 } }", "operationName": "Search__searchSubgraph__0", "operationKind": "query", "id": null, "inputRewrites": null, "outputRewrites": null, "contextRewrites": null, - "schemaAwareHash": "51a7aadec14b66d9f6c737be7418bac0be1af89fcc55dac55d9e9b125bc3682d", + "schemaAwareHash": "70b62e564b3924984694d90de2b10947a2f5c14ceb76d154f43bb3c638c4830b", "authorization": { "is_authenticated": false, "scopes": [], @@ -197,14 +197,14 @@ expression: response "variableUsages": [ "movieResultParam" ], - "operation": "query Search__artworkSubgraph__1($representations: [_Any!]!, $movieResultParam: String) { _entities(representations: $representations) { ... on EntityCollectionSection { title artwork(params: $movieResultParam) } ... on GallerySection { artwork(params: $movieResultParam) } } }", + "operation": "query Search__artworkSubgraph__1($representations: [_Any!]!, $movieResultParam: String) { _entities(representations: $representations) { ..._generated_onEntityCollectionSection2_0 ... on GallerySection { artwork(params: $movieResultParam) } } } fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection { title artwork(params: $movieResultParam) }", "operationName": "Search__artworkSubgraph__1", "operationKind": "query", "id": null, "inputRewrites": null, "outputRewrites": null, "contextRewrites": null, - "schemaAwareHash": "62ff891f6971184d3e42b98f8166be72027b5479f9ec098af460a48ea6f6cbf4", + "schemaAwareHash": "6510f6b9672829bd9217618b78ef6f329fbddb125f88184d04e6faaa982ff8bb", "authorization": { "is_authenticated": false, "scopes": [], @@ -258,14 +258,14 @@ expression: response "variableUsages": [ "articleResultParam" ], - "operation": "query Search__artworkSubgraph__2($representations: [_Any!]!, $articleResultParam: String) { _entities(representations: $representations) { ... on GallerySection { artwork(params: $articleResultParam) } ... on EntityCollectionSection { artwork(params: $articleResultParam) title } } }", + "operation": "query Search__artworkSubgraph__2($representations: [_Any!]!, $articleResultParam: String) { _entities(representations: $representations) { ... on GallerySection { artwork(params: $articleResultParam) } ..._generated_onEntityCollectionSection2_0 } } fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection { artwork(params: $articleResultParam) title }", "operationName": "Search__artworkSubgraph__2", "operationKind": "query", "id": null, "inputRewrites": null, "outputRewrites": null, "contextRewrites": null, - "schemaAwareHash": "7e6f6850777335eb1421a30a45f6888bb9e5d0acf8f55d576d55d1c4b7d23ec7", + "schemaAwareHash": "6bc34c108f7cf81896971bffad76dc5275d46231b4dfe492ccc205dda9a4aa16", "authorization": { "is_authenticated": false, "scopes": [], @@ -278,7 +278,7 @@ expression: response ] } }, - "text": "QueryPlan {\n Sequence {\n Fetch(service: \"searchSubgraph\") {\n {\n searchListOfList {\n __typename\n ... on MovieResult {\n sections {\n __typename\n ... on EntityCollectionSection {\n __typename\n id\n }\n ... on GallerySection {\n __typename\n id\n }\n }\n id\n }\n ... on ArticleResult {\n id\n sections {\n __typename\n ... on GallerySection {\n __typename\n id\n }\n ... on EntityCollectionSection {\n __typename\n id\n }\n }\n }\n }\n }\n },\n Parallel {\n Flatten(path: \".searchListOfList.@.@|[MovieResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on EntityCollectionSection {\n __typename\n id\n }\n ... on GallerySection {\n __typename\n id\n }\n } =>\n {\n ... on EntityCollectionSection {\n title\n artwork(params: $movieResultParam)\n }\n ... on GallerySection {\n artwork(params: $movieResultParam)\n }\n }\n },\n },\n Flatten(path: \".searchListOfList.@.@|[ArticleResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on GallerySection {\n __typename\n id\n }\n ... on EntityCollectionSection {\n __typename\n id\n }\n } =>\n {\n ... on GallerySection {\n artwork(params: $articleResultParam)\n }\n ... on EntityCollectionSection {\n artwork(params: $articleResultParam)\n title\n }\n }\n },\n },\n },\n },\n}" + "text": "QueryPlan {\n Sequence {\n Fetch(service: \"searchSubgraph\") {\n {\n searchListOfList {\n __typename\n ..._generated_onMovieResult2_0\n ..._generated_onArticleResult2_0\n }\n }\n \n fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection {\n __typename\n id\n }\n \n fragment _generated_onGallerySection2_0 on GallerySection {\n __typename\n id\n }\n \n fragment _generated_onMovieResult2_0 on MovieResult {\n sections {\n __typename\n ..._generated_onEntityCollectionSection2_0\n ..._generated_onGallerySection2_0\n }\n id\n }\n \n fragment _generated_onArticleResult2_0 on ArticleResult {\n id\n sections {\n __typename\n ..._generated_onGallerySection2_0\n ..._generated_onEntityCollectionSection2_0\n }\n }\n },\n Parallel {\n Flatten(path: \".searchListOfList.@.@|[MovieResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on EntityCollectionSection {\n __typename\n id\n }\n ... on GallerySection {\n __typename\n id\n }\n } =>\n {\n ..._generated_onEntityCollectionSection2_0\n ... on GallerySection {\n artwork(params: $movieResultParam)\n }\n }\n \n fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection {\n title\n artwork(params: $movieResultParam)\n }\n },\n },\n Flatten(path: \".searchListOfList.@.@|[ArticleResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on GallerySection {\n __typename\n id\n }\n ... on EntityCollectionSection {\n __typename\n id\n }\n } =>\n {\n ... on GallerySection {\n artwork(params: $articleResultParam)\n }\n ..._generated_onEntityCollectionSection2_0\n }\n \n fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection {\n artwork(params: $articleResultParam)\n title\n }\n },\n },\n },\n },\n}" } } } diff --git a/apollo-router/tests/snapshots/type_conditions___test_type_conditions_enabled_list_of_list_of_list-2.snap b/apollo-router/tests/snapshots/type_conditions___test_type_conditions_enabled_list_of_list_of_list-2.snap index f206e94c89..5cc97759df 100644 --- a/apollo-router/tests/snapshots/type_conditions___test_type_conditions_enabled_list_of_list_of_list-2.snap +++ b/apollo-router/tests/snapshots/type_conditions___test_type_conditions_enabled_list_of_list_of_list-2.snap @@ -138,14 +138,14 @@ expression: response "kind": "Fetch", "serviceName": "searchSubgraph", "variableUsages": [], - "operation": "query Search__searchSubgraph__0 { searchListOfListOfList { __typename ... on MovieResult { sections { __typename ... on EntityCollectionSection { __typename id } ... on GallerySection { __typename id } } id } ... on ArticleResult { id sections { __typename ... on GallerySection { __typename id } ... on EntityCollectionSection { __typename id } } } } }", + "operation": "query Search__searchSubgraph__0 { searchListOfListOfList { __typename ..._generated_onMovieResult2_0 ..._generated_onArticleResult2_0 } } fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection { __typename id } fragment _generated_onGallerySection2_0 on GallerySection { __typename id } fragment _generated_onMovieResult2_0 on MovieResult { sections { __typename ..._generated_onEntityCollectionSection2_0 ..._generated_onGallerySection2_0 } id } fragment _generated_onArticleResult2_0 on ArticleResult { id sections { __typename ..._generated_onGallerySection2_0 ..._generated_onEntityCollectionSection2_0 } }", "operationName": "Search__searchSubgraph__0", "operationKind": "query", "id": null, "inputRewrites": null, "outputRewrites": null, "contextRewrites": null, - "schemaAwareHash": "47d7643dd7226529814a57e0382aafb3790c2d8a8b26354aa2f60e9c9f097a05", + "schemaAwareHash": "cb374f6eaa19cb529eeae258f2b136dbc751e3784fdc279954e59622cfb1edde", "authorization": { "is_authenticated": false, "scopes": [], @@ -201,14 +201,14 @@ expression: response "variableUsages": [ "articleResultParam" ], - "operation": "query Search__artworkSubgraph__1($representations: [_Any!]!, $articleResultParam: String) { _entities(representations: $representations) { ... on GallerySection { artwork(params: $articleResultParam) } ... on EntityCollectionSection { artwork(params: $articleResultParam) title } } }", + "operation": "query Search__artworkSubgraph__1($representations: [_Any!]!, $articleResultParam: String) { _entities(representations: $representations) { ... on GallerySection { artwork(params: $articleResultParam) } ..._generated_onEntityCollectionSection2_0 } } fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection { artwork(params: $articleResultParam) title }", "operationName": "Search__artworkSubgraph__1", "operationKind": "query", "id": null, "inputRewrites": null, "outputRewrites": null, "contextRewrites": null, - "schemaAwareHash": "a0bf36d3a611df53c3a60b9b124a2887f2d266858221c606ace0985d101d64bd", + "schemaAwareHash": "1d21a65a3b5a31e17f7834750ef5b37fb49d99d0a1e2145f00a62d43c5f8423a", "authorization": { "is_authenticated": false, "scopes": [], @@ -262,14 +262,14 @@ expression: response "variableUsages": [ "movieResultParam" ], - "operation": "query Search__artworkSubgraph__2($representations: [_Any!]!, $movieResultParam: String) { _entities(representations: $representations) { ... on EntityCollectionSection { title artwork(params: $movieResultParam) } ... on GallerySection { artwork(params: $movieResultParam) } } }", + "operation": "query Search__artworkSubgraph__2($representations: [_Any!]!, $movieResultParam: String) { _entities(representations: $representations) { ..._generated_onEntityCollectionSection2_0 ... on GallerySection { artwork(params: $movieResultParam) } } } fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection { title artwork(params: $movieResultParam) }", "operationName": "Search__artworkSubgraph__2", "operationKind": "query", "id": null, "inputRewrites": null, "outputRewrites": null, "contextRewrites": null, - "schemaAwareHash": "3e84a53f967bf40d4c08254a94f3fa32a828ab3ad8184a22bb3439c596ecaaf4", + "schemaAwareHash": "df321f6532c2c9eda0d8c042e5f08073c24e558dd0cae01054886b79416a6c08", "authorization": { "is_authenticated": false, "scopes": [], @@ -282,7 +282,7 @@ expression: response ] } }, - "text": "QueryPlan {\n Sequence {\n Fetch(service: \"searchSubgraph\") {\n {\n searchListOfListOfList {\n __typename\n ... on MovieResult {\n sections {\n __typename\n ... on EntityCollectionSection {\n __typename\n id\n }\n ... on GallerySection {\n __typename\n id\n }\n }\n id\n }\n ... on ArticleResult {\n id\n sections {\n __typename\n ... on GallerySection {\n __typename\n id\n }\n ... on EntityCollectionSection {\n __typename\n id\n }\n }\n }\n }\n }\n },\n Parallel {\n Flatten(path: \"searchListOfListOfList.@.@.@|[ArticleResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on GallerySection {\n __typename\n id\n }\n ... on EntityCollectionSection {\n __typename\n id\n }\n } =>\n {\n ... on GallerySection {\n artwork(params: $articleResultParam)\n }\n ... on EntityCollectionSection {\n artwork(params: $articleResultParam)\n title\n }\n }\n },\n },\n Flatten(path: \"searchListOfListOfList.@.@.@|[MovieResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on EntityCollectionSection {\n __typename\n id\n }\n ... on GallerySection {\n __typename\n id\n }\n } =>\n {\n ... on EntityCollectionSection {\n title\n artwork(params: $movieResultParam)\n }\n ... on GallerySection {\n artwork(params: $movieResultParam)\n }\n }\n },\n },\n },\n },\n}" + "text": "QueryPlan {\n Sequence {\n Fetch(service: \"searchSubgraph\") {\n {\n searchListOfListOfList {\n __typename\n ..._generated_onMovieResult2_0\n ..._generated_onArticleResult2_0\n }\n }\n\n fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection {\n __typename\n id\n }\n\n fragment _generated_onGallerySection2_0 on GallerySection {\n __typename\n id\n }\n\n fragment _generated_onMovieResult2_0 on MovieResult {\n sections {\n __typename\n ..._generated_onEntityCollectionSection2_0\n ..._generated_onGallerySection2_0\n }\n id\n }\n\n fragment _generated_onArticleResult2_0 on ArticleResult {\n id\n sections {\n __typename\n ..._generated_onGallerySection2_0\n ..._generated_onEntityCollectionSection2_0\n }\n }\n },\n Parallel {\n Flatten(path: \"searchListOfListOfList.@.@.@|[ArticleResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on GallerySection {\n __typename\n id\n }\n ... on EntityCollectionSection {\n __typename\n id\n }\n } =>\n {\n ... on GallerySection {\n artwork(params: $articleResultParam)\n }\n ..._generated_onEntityCollectionSection2_0\n }\n\n fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection {\n artwork(params: $articleResultParam)\n title\n }\n },\n },\n Flatten(path: \"searchListOfListOfList.@.@.@|[MovieResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on EntityCollectionSection {\n __typename\n id\n }\n ... on GallerySection {\n __typename\n id\n }\n } =>\n {\n ..._generated_onEntityCollectionSection2_0\n ... on GallerySection {\n artwork(params: $movieResultParam)\n }\n }\n\n fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection {\n title\n artwork(params: $movieResultParam)\n }\n },\n },\n },\n },\n}" } } } diff --git a/apollo-router/tests/snapshots/type_conditions___test_type_conditions_enabled_list_of_list_of_list.snap b/apollo-router/tests/snapshots/type_conditions___test_type_conditions_enabled_list_of_list_of_list.snap index 78a539ec02..593bd573f6 100644 --- a/apollo-router/tests/snapshots/type_conditions___test_type_conditions_enabled_list_of_list_of_list.snap +++ b/apollo-router/tests/snapshots/type_conditions___test_type_conditions_enabled_list_of_list_of_list.snap @@ -138,14 +138,14 @@ expression: response "kind": "Fetch", "serviceName": "searchSubgraph", "variableUsages": [], - "operation": "query Search__searchSubgraph__0 { searchListOfListOfList { __typename ... on MovieResult { sections { __typename ... on EntityCollectionSection { __typename id } ... on GallerySection { __typename id } } id } ... on ArticleResult { id sections { __typename ... on GallerySection { __typename id } ... on EntityCollectionSection { __typename id } } } } }", + "operation": "query Search__searchSubgraph__0 { searchListOfListOfList { __typename ..._generated_onMovieResult2_0 ..._generated_onArticleResult2_0 } } fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection { __typename id } fragment _generated_onGallerySection2_0 on GallerySection { __typename id } fragment _generated_onMovieResult2_0 on MovieResult { sections { __typename ..._generated_onEntityCollectionSection2_0 ..._generated_onGallerySection2_0 } id } fragment _generated_onArticleResult2_0 on ArticleResult { id sections { __typename ..._generated_onGallerySection2_0 ..._generated_onEntityCollectionSection2_0 } }", "operationName": "Search__searchSubgraph__0", "operationKind": "query", "id": null, "inputRewrites": null, "outputRewrites": null, "contextRewrites": null, - "schemaAwareHash": "e6f45a784fb669930586f13fc587f55798089a87ee4b23a7d1736e0516367a6a", + "schemaAwareHash": "26ae1da614855e4edee344061c0fc95ec4613a99e012de1f33207cb5318487b8", "authorization": { "is_authenticated": false, "scopes": [], @@ -202,14 +202,14 @@ expression: response "variableUsages": [ "movieResultParam" ], - "operation": "query Search__artworkSubgraph__1($representations: [_Any!]!, $movieResultParam: String) { _entities(representations: $representations) { ... on EntityCollectionSection { title artwork(params: $movieResultParam) } ... on GallerySection { artwork(params: $movieResultParam) } } }", + "operation": "query Search__artworkSubgraph__1($representations: [_Any!]!, $movieResultParam: String) { _entities(representations: $representations) { ..._generated_onEntityCollectionSection2_0 ... on GallerySection { artwork(params: $movieResultParam) } } } fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection { title artwork(params: $movieResultParam) }", "operationName": "Search__artworkSubgraph__1", "operationKind": "query", "id": null, "inputRewrites": null, "outputRewrites": null, "contextRewrites": null, - "schemaAwareHash": "62ff891f6971184d3e42b98f8166be72027b5479f9ec098af460a48ea6f6cbf4", + "schemaAwareHash": "6510f6b9672829bd9217618b78ef6f329fbddb125f88184d04e6faaa982ff8bb", "authorization": { "is_authenticated": false, "scopes": [], @@ -264,14 +264,14 @@ expression: response "variableUsages": [ "articleResultParam" ], - "operation": "query Search__artworkSubgraph__2($representations: [_Any!]!, $articleResultParam: String) { _entities(representations: $representations) { ... on GallerySection { artwork(params: $articleResultParam) } ... on EntityCollectionSection { artwork(params: $articleResultParam) title } } }", + "operation": "query Search__artworkSubgraph__2($representations: [_Any!]!, $articleResultParam: String) { _entities(representations: $representations) { ... on GallerySection { artwork(params: $articleResultParam) } ..._generated_onEntityCollectionSection2_0 } } fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection { artwork(params: $articleResultParam) title }", "operationName": "Search__artworkSubgraph__2", "operationKind": "query", "id": null, "inputRewrites": null, "outputRewrites": null, "contextRewrites": null, - "schemaAwareHash": "7e6f6850777335eb1421a30a45f6888bb9e5d0acf8f55d576d55d1c4b7d23ec7", + "schemaAwareHash": "6bc34c108f7cf81896971bffad76dc5275d46231b4dfe492ccc205dda9a4aa16", "authorization": { "is_authenticated": false, "scopes": [], @@ -284,7 +284,7 @@ expression: response ] } }, - "text": "QueryPlan {\n Sequence {\n Fetch(service: \"searchSubgraph\") {\n {\n searchListOfListOfList {\n __typename\n ... on MovieResult {\n sections {\n __typename\n ... on EntityCollectionSection {\n __typename\n id\n }\n ... on GallerySection {\n __typename\n id\n }\n }\n id\n }\n ... on ArticleResult {\n id\n sections {\n __typename\n ... on GallerySection {\n __typename\n id\n }\n ... on EntityCollectionSection {\n __typename\n id\n }\n }\n }\n }\n }\n },\n Parallel {\n Flatten(path: \".searchListOfListOfList.@.@.@|[MovieResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on EntityCollectionSection {\n __typename\n id\n }\n ... on GallerySection {\n __typename\n id\n }\n } =>\n {\n ... on EntityCollectionSection {\n title\n artwork(params: $movieResultParam)\n }\n ... on GallerySection {\n artwork(params: $movieResultParam)\n }\n }\n },\n },\n Flatten(path: \".searchListOfListOfList.@.@.@|[ArticleResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on GallerySection {\n __typename\n id\n }\n ... on EntityCollectionSection {\n __typename\n id\n }\n } =>\n {\n ... on GallerySection {\n artwork(params: $articleResultParam)\n }\n ... on EntityCollectionSection {\n artwork(params: $articleResultParam)\n title\n }\n }\n },\n },\n },\n },\n}" + "text": "QueryPlan {\n Sequence {\n Fetch(service: \"searchSubgraph\") {\n {\n searchListOfListOfList {\n __typename\n ..._generated_onMovieResult2_0\n ..._generated_onArticleResult2_0\n }\n }\n \n fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection {\n __typename\n id\n }\n \n fragment _generated_onGallerySection2_0 on GallerySection {\n __typename\n id\n }\n \n fragment _generated_onMovieResult2_0 on MovieResult {\n sections {\n __typename\n ..._generated_onEntityCollectionSection2_0\n ..._generated_onGallerySection2_0\n }\n id\n }\n \n fragment _generated_onArticleResult2_0 on ArticleResult {\n id\n sections {\n __typename\n ..._generated_onGallerySection2_0\n ..._generated_onEntityCollectionSection2_0\n }\n }\n },\n Parallel {\n Flatten(path: \".searchListOfListOfList.@.@.@|[MovieResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on EntityCollectionSection {\n __typename\n id\n }\n ... on GallerySection {\n __typename\n id\n }\n } =>\n {\n ..._generated_onEntityCollectionSection2_0\n ... on GallerySection {\n artwork(params: $movieResultParam)\n }\n }\n \n fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection {\n title\n artwork(params: $movieResultParam)\n }\n },\n },\n Flatten(path: \".searchListOfListOfList.@.@.@|[ArticleResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on GallerySection {\n __typename\n id\n }\n ... on EntityCollectionSection {\n __typename\n id\n }\n } =>\n {\n ... on GallerySection {\n artwork(params: $articleResultParam)\n }\n ..._generated_onEntityCollectionSection2_0\n }\n \n fragment _generated_onEntityCollectionSection2_0 on EntityCollectionSection {\n artwork(params: $articleResultParam)\n title\n }\n },\n },\n },\n },\n}" } } } diff --git a/apollo-router/tests/tracing_common/mod.rs b/apollo-router/tests/tracing_common/mod.rs index 0eda97f796..f7f698b87f 100644 --- a/apollo-router/tests/tracing_common/mod.rs +++ b/apollo-router/tests/tracing_common/mod.rs @@ -426,7 +426,15 @@ pub(crate) fn subgraph_mocks(subgraph: &str) -> subgraph::BoxService { }; builder.with_json( json!({ - "query": "query($representations:[_Any!]!){_entities(representations:$representations){...on Product{reviews{author{__typename id}}}}}", + "query": " + query($representations: [_Any!]!) { + _entities(representations: $representations) { + ..._generated_onProduct1_0 + } + } + fragment _generated_onProduct1_0 on Product { + reviews { author{ __typename id } } + }", "variables": {"representations": [ {"__typename": "Product", "upc": "1"}, {"__typename": "Product", "upc": "2"}, diff --git a/apollo-router/tests/type_conditions.rs b/apollo-router/tests/type_conditions.rs index 88757228b8..ab43b3f521 100644 --- a/apollo-router/tests/type_conditions.rs +++ b/apollo-router/tests/type_conditions.rs @@ -118,9 +118,6 @@ async fn _test_type_conditions_enabled_generate_query_fragments(planner_mode: &s json! {{ "experimental_type_conditioned_fetching": true, "experimental_query_planner_mode": planner_mode, - "supergraph": { - "generate_query_fragments": true - }, // will make debugging easier "plugins": { "experimental.expose_query_plan": true @@ -321,6 +318,10 @@ async fn _test_type_conditions_enabled_shouldnt_make_article_fetch(planner_mode: "plugins": { "experimental.expose_query_plan": true }, + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "supergraph": { + "generate_query_fragments": false, + }, "include_subgraph_errors": { "all": true } diff --git a/docs/source/reference/router/configuration.mdx b/docs/source/reference/router/configuration.mdx index 3c89326a73..42597a9e57 100644 --- a/docs/source/reference/router/configuration.mdx +++ b/docs/source/reference/router/configuration.mdx @@ -1236,22 +1236,29 @@ example: password: "${env.MY_PASSWORD}" #highlight-line ``` -### Fragment reuse and generation + + +### Fragment generation and reuse -By default, the router will attempt to reuse fragments from the original query while forming subgraph requests. This behavior can be disabled by setting the option to `false`: +By default, the router compresses subgraph requests by generating fragment +definitions based on the shape of the subgraph operation. In many cases this +significantly reduces the size of the query sent to subgraphs. -```yaml -supergraph: - experimental_reuse_query_fragments: false -``` - -Alternatively, the router can be configured to _generate_ fragments for subgraph requests. When set to `true`, the router will extract _inline fragments only_ into fragment definitions before sending queries to subgraphs. This can significantly reduce the size of the query sent to subgraphs, but may increase the time it takes for planning. Note that this option and `experimental_reuse_query_fragments` are mutually exclusive; if both are explicitly set to `true`, `generate_query_fragments` will take precedence. +The router also supports an experimental algorithm that attempts to reuse fragments +from the original operation while forming subgraph requests. This experimental feature +used to be enabled by default, but is still available to support subgraphs that rely +on the specific shape of fragments in an operation: ```yaml supergraph: - generate_query_fragments: true + generate_query_fragments: false + experimental_reuse_query_fragments: true ``` +Note that `generate_query_fragments` and `experimental_reuse_query_fragments` are +mutually exclusive; if both are explicitly set to `true`, `generate_query_fragments` +will take precedence. + In the future, the `generate_query_fragments` option will be the only option for handling fragments. From defd699fe2345865c4f315e42635029db40f50da Mon Sep 17 00:00:00 2001 From: Andrew Carlson <5479270+andrewicarlson@users.noreply.github.com> Date: Wed, 13 Nov 2024 14:09:32 -0600 Subject: [PATCH 34/77] Fixed an issue with the formatting of the Entity Cache Invalidation diagram --- docs/source/routing/performance/caching/entity.mdx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/source/routing/performance/caching/entity.mdx b/docs/source/routing/performance/caching/entity.mdx index d251c19e7e..db9c5772e5 100644 --- a/docs/source/routing/performance/caching/entity.mdx +++ b/docs/source/routing/performance/caching/entity.mdx @@ -216,7 +216,6 @@ This entry contains an object with the `all` field to affect all subgraph reques ### Entity cache invalidation ```mermaid -%%{init: {"flowchart": {"htmlLabels": false}} }%% flowchart RL subgraph QueryResponse["Cache invalidation POST"] n1["{ @@ -236,14 +235,14 @@ flowchart RL end subgraph PriceQueryFragment["Price Query Fragment (e.g. TTL 2200)"] - n2["` ฬถ{ฬถ + n2[" ฬถ{ฬถ   " ฬถpฬถrฬถiฬถcฬถeฬถ": ฬถ{ฬถ     " ฬถiฬถdฬถ": ฬถ1ฬถ0ฬถ1ฬถ,     " ฬถpฬถrฬถoฬถdฬถuฬถcฬถtฬถ_ฬถiฬถdฬถ": ฬถ1ฬถ2ฬถ,     " ฬถaฬถmฬถoฬถuฬถnฬถtฬถ": ฬถ1ฬถ5ฬถ0ฬถ0ฬถ,     "ฬถcฬถuฬถrฬถrฬถeฬถnฬถcฬถyฬถ_ฬถcฬถoฬถdฬถeฬถ": " ฬถUฬถSฬถDฬถ"    ฬถ}ฬถ - ฬถ}ฬถ`"] + ฬถ}ฬถ"] end Router From 4dc075113155126fe0980d46a09b402bf1ae3c4b Mon Sep 17 00:00:00 2001 From: Andrew Carlson <5479270+andrewicarlson@users.noreply.github.com> Date: Wed, 13 Nov 2024 14:13:30 -0600 Subject: [PATCH 35/77] Added a title to the invalidation diagram --- docs/source/routing/performance/caching/entity.mdx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/source/routing/performance/caching/entity.mdx b/docs/source/routing/performance/caching/entity.mdx index db9c5772e5..6bfe513b2a 100644 --- a/docs/source/routing/performance/caching/entity.mdx +++ b/docs/source/routing/performance/caching/entity.mdx @@ -83,8 +83,6 @@ flowchart RL }"] end - - subgraph Subgraphs["Subgraphs"] Purchases["Purchases"] Inventory["Inventory"] @@ -216,6 +214,10 @@ This entry contains an object with the `all` field to affect all subgraph reques ### Entity cache invalidation ```mermaid +--- +title: Invalidating an Entity Cache +--- + flowchart RL subgraph QueryResponse["Cache invalidation POST"] n1["{ From e6224cb88461006752a24c74df9f7261102e48b2 Mon Sep 17 00:00:00 2001 From: Andrew Carlson <5479270+andrewicarlson@users.noreply.github.com> Date: Thu, 14 Nov 2024 12:52:06 -0600 Subject: [PATCH 36/77] Update docs/source/routing/performance/caching/entity.mdx Co-authored-by: Maria Elisabeth Schreiber --- docs/source/routing/performance/caching/entity.mdx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/source/routing/performance/caching/entity.mdx b/docs/source/routing/performance/caching/entity.mdx index 6bfe513b2a..44b865a419 100644 --- a/docs/source/routing/performance/caching/entity.mdx +++ b/docs/source/routing/performance/caching/entity.mdx @@ -61,10 +61,9 @@ With entity caching enabled for this example, the router can: - Cache the cart per user, with a small amount of data. - Cache inventory data with a short TTL or not cache it at all. +For example, the diagram below shows how a price entity can be cached and then combined with purchase and inventory fragments to serve a `products` query. Because price data is subject to change less often than inventory data, it makes sense to cache it with a different TTL. + ```mermaid ---- -title: Entity Caching using the "Price" entity ---- flowchart RL subgraph QueryResponse["JSON Response"] n1["{ From 00bf83affa41d46c81aad0c6d281fa51ccb68872 Mon Sep 17 00:00:00 2001 From: Andrew Carlson <5479270+andrewicarlson@users.noreply.github.com> Date: Thu, 14 Nov 2024 12:52:26 -0600 Subject: [PATCH 37/77] Update docs/source/routing/performance/caching/entity.mdx Co-authored-by: Maria Elisabeth Schreiber --- docs/source/routing/performance/caching/entity.mdx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/source/routing/performance/caching/entity.mdx b/docs/source/routing/performance/caching/entity.mdx index 44b865a419..409acac085 100644 --- a/docs/source/routing/performance/caching/entity.mdx +++ b/docs/source/routing/performance/caching/entity.mdx @@ -212,10 +212,9 @@ This entry contains an object with the `all` field to affect all subgraph reques ### Entity cache invalidation +You can invalidate entity cache entries with a [specifically formatted request](#invalidation-request-format once you [configure your router](#configuration) appropriately. For example, if price data changes before a price entity's TTL expires, you can send an invalidation request. + ```mermaid ---- -title: Invalidating an Entity Cache ---- flowchart RL subgraph QueryResponse["Cache invalidation POST"] From 46ee5c76ac685d44c3a96da3e56f434bfd040d5f Mon Sep 17 00:00:00 2001 From: Andrew Carlson <5479270+andrewicarlson@users.noreply.github.com> Date: Thu, 14 Nov 2024 12:53:52 -0600 Subject: [PATCH 38/77] Update docs/source/routing/performance/caching/entity.mdx --- docs/source/routing/performance/caching/entity.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/routing/performance/caching/entity.mdx b/docs/source/routing/performance/caching/entity.mdx index 409acac085..76e9a616b1 100644 --- a/docs/source/routing/performance/caching/entity.mdx +++ b/docs/source/routing/performance/caching/entity.mdx @@ -248,7 +248,7 @@ flowchart RL Router Database[("   ")] - Router --> QueryResponse + QueryResponse --> Router Purchases --> Router Inventory --> Router Price --- Router From a22c838af48bf06c22a32878399d4cd7d37ac9f3 Mon Sep 17 00:00:00 2001 From: Geoffroy Couprie Date: Fri, 15 Nov 2024 10:43:04 +0100 Subject: [PATCH 39/77] Pass parameters explicitely in QueryPlannerRequest instead of context (#6208) --- apollo-router/src/error.rs | 14 +++ .../cost_calculator/static_cost.rs | 12 ++- .../src/query_planner/bridge_query_planner.rs | 47 +------- .../bridge_query_planner_pool.rs | 20 +++- .../query_planner/caching_query_planner.rs | 102 +++++------------- apollo-router/src/services/query_planner.rs | 26 +++-- .../src/services/supergraph/service.rs | 6 +- .../apollo_otel_traces__condition_else-2.snap | 2 +- .../apollo_otel_traces__condition_else.snap | 2 +- .../apollo_otel_traces__condition_if-2.snap | 2 +- .../apollo_otel_traces__condition_if.snap | 2 +- .../apollo_reports__condition_else-2.snap | 2 +- .../apollo_reports__condition_else.snap | 2 +- .../apollo_reports__condition_if-2.snap | 2 +- .../apollo_reports__condition_if.snap | 2 +- 15 files changed, 98 insertions(+), 145 deletions(-) diff --git a/apollo-router/src/error.rs b/apollo-router/src/error.rs index b6281a58d6..d78cd86728 100644 --- a/apollo-router/src/error.rs +++ b/apollo-router/src/error.rs @@ -1,4 +1,5 @@ //! Router errors. +use std::collections::HashMap; use std::sync::Arc; use apollo_compiler::validation::DiagnosticList; @@ -412,6 +413,19 @@ impl IntoGraphQLErrors for QueryPlannerError { } } +impl QueryPlannerError { + pub(crate) fn usage_reporting(&self) -> Option { + match self { + QueryPlannerError::PlanningErrors(pe) => Some(pe.usage_reporting.clone()), + QueryPlannerError::SpecError(e) => Some(UsageReporting { + stats_report_key: e.get_error_key().to_string(), + referenced_fields_by_type: HashMap::new(), + }), + _ => None, + } + } +} + #[derive(Clone, Debug, Error, Serialize, Deserialize)] /// Container for planner setup errors pub(crate) struct PlannerErrors(Arc>); diff --git a/apollo-router/src/plugins/demand_control/cost_calculator/static_cost.rs b/apollo-router/src/plugins/demand_control/cost_calculator/static_cost.rs index 98f3f275ed..3c0d973ebb 100644 --- a/apollo-router/src/plugins/demand_control/cost_calculator/static_cost.rs +++ b/apollo-router/src/plugins/demand_control/cost_calculator/static_cost.rs @@ -578,11 +578,13 @@ mod tests { use ahash::HashMapExt; use apollo_federation::query_plan::query_planner::QueryPlanner; use bytes::Bytes; + use router_bridge::planner::PlanOptions; use test_log::test; use tower::Service; use super::*; use crate::introspection::IntrospectionCache; + use crate::plugins::authorization::CacheKeyMetadata; use crate::query_planner::BridgeQueryPlanner; use crate::services::layers::query_analysis::ParsedDocument; use crate::services::QueryPlannerContent; @@ -681,10 +683,16 @@ mod tests { let ctx = Context::new(); ctx.extensions() - .with_lock(|mut lock| lock.insert::(query)); + .with_lock(|mut lock| lock.insert::(query.clone())); let planner_res = planner - .call(QueryPlannerRequest::new(query_str.to_string(), None, ctx)) + .call(QueryPlannerRequest::new( + query_str.to_string(), + None, + query, + CacheKeyMetadata::default(), + PlanOptions::default(), + )) .await .unwrap(); let query_plan = match planner_res.content.unwrap() { diff --git a/apollo-router/src/query_planner/bridge_query_planner.rs b/apollo-router/src/query_planner/bridge_query_planner.rs index f10e424bb3..e3cc52dcdd 100644 --- a/apollo-router/src/query_planner/bridge_query_planner.rs +++ b/apollo-router/src/query_planner/bridge_query_planner.rs @@ -43,7 +43,6 @@ use crate::metrics::meter_provider; use crate::plugins::authorization::AuthorizationPlugin; use crate::plugins::authorization::CacheKeyMetadata; use crate::plugins::authorization::UnauthorizedPaths; -use crate::plugins::progressive_override::LABELS_TO_OVERRIDE_KEY; use crate::plugins::telemetry::config::ApolloSignatureNormalizationAlgorithm; use crate::plugins::telemetry::config::Conf as TelemetryConfig; use crate::query_planner::convert::convert_root_query_plan_node; @@ -594,21 +593,14 @@ impl Service for BridgeQueryPlanner { let QueryPlannerRequest { query: original_query, operation_name, - context, + document, + metadata, + plan_options, } = req; - let metadata = context - .extensions() - .with_lock(|lock| lock.get::().cloned().unwrap_or_default()); let this = self.clone(); let fut = async move { - let mut doc = match context - .extensions() - .with_lock(|lock| lock.get::().cloned()) - { - None => return Err(QueryPlannerError::SpecError(SpecError::UnknownFileId)), - Some(d) => d, - }; + let mut doc = document; let api_schema = this.schema.api_schema(); match add_defer_labels(api_schema, &doc.ast) { @@ -635,19 +627,9 @@ impl Service for BridgeQueryPlanner { operation_name.as_deref(), Arc::new(QueryHash(hash)), )?; - context - .extensions() - .with_lock(|mut lock| lock.insert::(doc.clone())); } } - let plan_options = PlanOptions { - override_conditions: context - .get(LABELS_TO_OVERRIDE_KEY) - .unwrap_or_default() - .unwrap_or_default(), - }; - let res = this .get( QueryKey { @@ -664,27 +646,8 @@ impl Service for BridgeQueryPlanner { match res { Ok(query_planner_content) => Ok(QueryPlannerResponse::builder() .content(query_planner_content) - .context(context) .build()), - Err(e) => { - match &e { - QueryPlannerError::PlanningErrors(pe) => { - context.extensions().with_lock(|mut lock| { - lock.insert(Arc::new(pe.usage_reporting.clone())) - }); - } - QueryPlannerError::SpecError(e) => { - context.extensions().with_lock(|mut lock| { - lock.insert(Arc::new(UsageReporting { - stats_report_key: e.get_error_key().to_string(), - referenced_fields_by_type: HashMap::new(), - })) - }); - } - _ => (), - } - Err(e) - } + Err(e) => Err(e), } }; diff --git a/apollo-router/src/query_planner/bridge_query_planner_pool.rs b/apollo-router/src/query_planner/bridge_query_planner_pool.rs index 722a965efd..652bc997b9 100644 --- a/apollo-router/src/query_planner/bridge_query_planner_pool.rs +++ b/apollo-router/src/query_planner/bridge_query_planner_pool.rs @@ -300,9 +300,11 @@ impl tower::Service for BridgeQueryPlannerPool { mod tests { use opentelemetry_sdk::metrics::data::Gauge; + use router_bridge::planner::PlanOptions; use super::*; use crate::metrics::FutureMetricsExt; + use crate::plugins::authorization::CacheKeyMetadata; use crate::spec::Query; use crate::Context; @@ -326,11 +328,19 @@ mod tests { let doc = Query::parse_document(&query, None, &schema, &config).unwrap(); let context = Context::new(); - context.extensions().with_lock(|mut lock| lock.insert(doc)); - - pool.call(QueryPlannerRequest::new(query, None, context)) - .await - .unwrap(); + context + .extensions() + .with_lock(|mut lock| lock.insert(doc.clone())); + + pool.call(QueryPlannerRequest::new( + query, + None, + doc, + CacheKeyMetadata::default(), + PlanOptions::default(), + )) + .await + .unwrap(); let metrics = crate::metrics::collect_metrics(); let heap_used = metrics.find("apollo.router.v8.heap.used").unwrap(); diff --git a/apollo-router/src/query_planner/caching_query_planner.rs b/apollo-router/src/query_planner/caching_query_planner.rs index 688ce1c697..ba65ba52a6 100644 --- a/apollo-router/src/query_planner/caching_query_planner.rs +++ b/apollo-router/src/query_planner/caching_query_planner.rs @@ -1,7 +1,6 @@ use std::collections::HashMap; use std::hash::Hash; use std::hash::Hasher; -use std::ops::Deref; use std::sync::Arc; use std::task; @@ -36,7 +35,6 @@ use crate::plugins::authorization::CacheKeyMetadata; use crate::plugins::progressive_override::LABELS_TO_OVERRIDE_KEY; use crate::plugins::telemetry::utils::Timer; use crate::query_planner::fetch::SubgraphSchemas; -use crate::query_planner::labeler::add_defer_labels; use crate::query_planner::BridgeQueryPlannerPool; use crate::query_planner::QueryPlanResult; use crate::services::layers::persisted_queries::PersistedQueryLayer; @@ -49,7 +47,6 @@ use crate::services::QueryPlannerResponse; use crate::spec::Schema; use crate::spec::SpecError; use crate::Configuration; -use crate::Context; /// An [`IndexMap`] of available plugins. pub(crate) type Plugins = IndexMap>; @@ -274,7 +271,7 @@ where let mut count = 0usize; let mut reused = 0usize; for WarmUpCachingQueryKey { - mut query, + query, operation_name, hash, metadata, @@ -282,7 +279,6 @@ where config_mode: _, } in all_cache_keys { - let context = Context::new(); let doc = match query_analysis .parse_document(&query, operation_name.as_deref()) .await @@ -340,25 +336,12 @@ where } }; - let schema = self.schema.api_schema(); - if let Ok(modified_query) = add_defer_labels(schema, &doc.ast) { - query = modified_query.to_string(); - } - - context.extensions().with_lock(|mut lock| { - lock.insert::(doc); - lock.insert(caching_key.metadata) - }); - - let _ = context.insert( - LABELS_TO_OVERRIDE_KEY, - caching_key.plan_options.override_conditions.clone(), - ); - let request = QueryPlannerRequest { query, operation_name, - context: context.clone(), + document: doc, + metadata: caching_key.metadata, + plan_options: caching_key.plan_options, }; let res = match service.ready().await { @@ -429,16 +412,16 @@ where let qp = self.clone(); Box::pin(async move { let context = request.context.clone(); - qp.plan(request).await.inspect(|response| { + qp.plan(request).await.inspect(|_response| { if let Some(usage_reporting) = context .extensions() .with_lock(|lock| lock.get::>().cloned()) { - let _ = response.context.insert( + let _ = context.insert( APOLLO_OPERATION_ID, stats_report_key_hash(usage_reporting.stats_report_key.as_str()), ); - let _ = response.context.insert( + let _ = context.insert( "apollo_operation_signature", usage_reporting.stats_report_key.clone(), ); @@ -516,20 +499,17 @@ where .await; if entry.is_first() { let query_planner::CachingRequest { - mut query, + query, operation_name, context, } = request; - let schema = self.schema.api_schema(); - if let Ok(modified_query) = add_defer_labels(schema, &doc.ast) { - query = modified_query.to_string(); - } - let request = QueryPlannerRequest::builder() .query(query) .and_operation_name(operation_name) - .context(context) + .document(doc) + .metadata(caching_key.metadata) + .plan_options(caching_key.plan_options) .build(); // some clients might timeout and cancel the request before query planning is finished, @@ -541,11 +521,7 @@ where let res = self.delegate.ready().await?.call(request).await; match res { - Ok(QueryPlannerResponse { - content, - context, - errors, - }) => { + Ok(QueryPlannerResponse { content, errors }) => { if let Some(content) = content.clone() { let can_cache = match &content { // Already cached in an introspection-specific, small-size, @@ -569,11 +545,7 @@ where lock.insert::>(plan.usage_reporting.clone()) }); } - Ok(QueryPlannerResponse { - content, - context, - errors, - }) + Ok(QueryPlannerResponse { content, errors }) } Err(error) => { let e = Arc::new(error); @@ -581,6 +553,11 @@ where tokio::spawn(async move { entry.insert(Err(err)).await; }); + if let Some(usage_reporting) = e.usage_reporting() { + context.extensions().with_lock(|mut lock| { + lock.insert::>(Arc::new(usage_reporting)); + }); + } Err(CacheResolverError::RetrievalError(e)) } } @@ -607,29 +584,13 @@ where }); } - Ok(QueryPlannerResponse::builder() - .content(content) - .context(context) - .build()) + Ok(QueryPlannerResponse::builder().content(content).build()) } Err(error) => { - match error.deref() { - QueryPlannerError::PlanningErrors(pe) => { - request.context.extensions().with_lock(|mut lock| { - lock.insert::>(Arc::new( - pe.usage_reporting.clone(), - )) - }); - } - QueryPlannerError::SpecError(e) => { - request.context.extensions().with_lock(|mut lock| { - lock.insert::>(Arc::new(UsageReporting { - stats_report_key: e.get_error_key().to_string(), - referenced_fields_by_type: HashMap::new(), - })) - }); - } - _ => {} + if let Some(usage_reporting) = error.usage_reporting() { + context.extensions().with_lock(|mut lock| { + lock.insert::>(Arc::new(usage_reporting)); + }); } Err(CacheResolverError::RetrievalError(error)) @@ -750,6 +711,7 @@ mod tests { use crate::spec::Query; use crate::spec::Schema; use crate::Configuration; + use crate::Context; mock! { #[derive(Debug)] @@ -892,10 +854,7 @@ mod tests { plan: Arc::new(query_plan), }; - Ok(QueryPlannerResponse::builder() - .content(qp_content) - .context(Context::new()) - .build()) + Ok(QueryPlannerResponse::builder().content(qp_content).build()) }); planner }); @@ -929,15 +888,15 @@ mod tests { .with_lock(|mut lock| lock.insert::(doc)); for _ in 0..5 { - assert!(planner + let _ = planner .call(query_planner::CachingRequest::new( "query Me { me { username } }".to_string(), Some("".into()), context.clone(), )) .await - .unwrap() - .context + .unwrap(); + assert!(context .extensions() .with_lock(|lock| lock.contains_key::>())); } @@ -970,10 +929,7 @@ mod tests { ), }; - Ok(QueryPlannerResponse::builder() - .content(qp_content) - .context(Context::new()) - .build()) + Ok(QueryPlannerResponse::builder().content(qp_content).build()) }); planner }); diff --git a/apollo-router/src/services/query_planner.rs b/apollo-router/src/services/query_planner.rs index 494bb7e2c7..d23a0e2ace 100644 --- a/apollo-router/src/services/query_planner.rs +++ b/apollo-router/src/services/query_planner.rs @@ -4,10 +4,12 @@ use std::sync::Arc; use async_trait::async_trait; use derivative::Derivative; +use router_bridge::planner::PlanOptions; use serde::Deserialize; use serde::Serialize; use static_assertions::assert_impl_all; +use super::layers::query_analysis::ParsedDocument; use crate::error::QueryPlannerError; use crate::graphql; use crate::query_planner::QueryPlan; @@ -20,7 +22,9 @@ assert_impl_all!(Request: Send); pub(crate) struct Request { pub(crate) query: String, pub(crate) operation_name: Option, - pub(crate) context: Context, + pub(crate) document: ParsedDocument, + pub(crate) metadata: crate::plugins::authorization::CacheKeyMetadata, + pub(crate) plan_options: PlanOptions, } #[buildstructor::buildstructor] @@ -29,11 +33,19 @@ impl Request { /// /// Required parameters are required in non-testing code to create a QueryPlannerRequest. #[builder] - pub(crate) fn new(query: String, operation_name: Option, context: Context) -> Request { + pub(crate) fn new( + query: String, + operation_name: Option, + document: ParsedDocument, + metadata: crate::plugins::authorization::CacheKeyMetadata, + plan_options: PlanOptions, + ) -> Request { Self { query, operation_name, - context, + document, + metadata, + plan_options, } } } @@ -72,7 +84,6 @@ pub(crate) struct Response { /// Optional in case of error pub(crate) content: Option, pub(crate) errors: Vec, - pub(crate) context: Context, } /// Query, QueryPlan and Introspection data. @@ -92,14 +103,9 @@ impl Response { #[builder] pub(crate) fn new( content: Option, - context: Context, errors: Vec, ) -> Response { - Self { - content, - context, - errors, - } + Self { content, errors } } } diff --git a/apollo-router/src/services/supergraph/service.rs b/apollo-router/src/services/supergraph/service.rs index a217df0bd1..f87c81727f 100644 --- a/apollo-router/src/services/supergraph/service.rs +++ b/apollo-router/src/services/supergraph/service.rs @@ -171,11 +171,7 @@ async fn service_call( let body = req.supergraph_request.body(); let variables = body.variables.clone(); - let QueryPlannerResponse { - content, - context, - errors, - } = match plan_query( + let QueryPlannerResponse { content, errors } = match plan_query( planning, body.operation_name.clone(), context.clone(), diff --git a/apollo-router/tests/snapshots/apollo_otel_traces__condition_else-2.snap b/apollo-router/tests/snapshots/apollo_otel_traces__condition_else-2.snap index 853672e8d0..602929d475 100644 --- a/apollo-router/tests/snapshots/apollo_otel_traces__condition_else-2.snap +++ b/apollo-router/tests/snapshots/apollo_otel_traces__condition_else-2.snap @@ -271,7 +271,7 @@ resourceSpans: stringValue: "[redacted]" - key: apollo_private.operation_signature value: - stringValue: "# -\nquery($if:Boolean!){topProducts{name...@defer(if:$if,label:\"\"){reviews{author{name}}reviews{author{name}}}}}" + stringValue: "# -\nquery($if:Boolean!){topProducts{name...@defer(if:$if){reviews{author{name}}reviews{author{name}}}}}" - key: apollo_private.query.aliases value: intValue: 0 diff --git a/apollo-router/tests/snapshots/apollo_otel_traces__condition_else.snap b/apollo-router/tests/snapshots/apollo_otel_traces__condition_else.snap index 853672e8d0..602929d475 100644 --- a/apollo-router/tests/snapshots/apollo_otel_traces__condition_else.snap +++ b/apollo-router/tests/snapshots/apollo_otel_traces__condition_else.snap @@ -271,7 +271,7 @@ resourceSpans: stringValue: "[redacted]" - key: apollo_private.operation_signature value: - stringValue: "# -\nquery($if:Boolean!){topProducts{name...@defer(if:$if,label:\"\"){reviews{author{name}}reviews{author{name}}}}}" + stringValue: "# -\nquery($if:Boolean!){topProducts{name...@defer(if:$if){reviews{author{name}}reviews{author{name}}}}}" - key: apollo_private.query.aliases value: intValue: 0 diff --git a/apollo-router/tests/snapshots/apollo_otel_traces__condition_if-2.snap b/apollo-router/tests/snapshots/apollo_otel_traces__condition_if-2.snap index 1b4bcb3cf1..69ea7edf5b 100644 --- a/apollo-router/tests/snapshots/apollo_otel_traces__condition_if-2.snap +++ b/apollo-router/tests/snapshots/apollo_otel_traces__condition_if-2.snap @@ -271,7 +271,7 @@ resourceSpans: stringValue: "[redacted]" - key: apollo_private.operation_signature value: - stringValue: "# -\nquery($if:Boolean!){topProducts{name...@defer(if:$if,label:\"\"){reviews{author{name}}reviews{author{name}}}}}" + stringValue: "# -\nquery($if:Boolean!){topProducts{name...@defer(if:$if){reviews{author{name}}reviews{author{name}}}}}" - key: apollo_private.query.aliases value: intValue: 0 diff --git a/apollo-router/tests/snapshots/apollo_otel_traces__condition_if.snap b/apollo-router/tests/snapshots/apollo_otel_traces__condition_if.snap index 1b4bcb3cf1..69ea7edf5b 100644 --- a/apollo-router/tests/snapshots/apollo_otel_traces__condition_if.snap +++ b/apollo-router/tests/snapshots/apollo_otel_traces__condition_if.snap @@ -271,7 +271,7 @@ resourceSpans: stringValue: "[redacted]" - key: apollo_private.operation_signature value: - stringValue: "# -\nquery($if:Boolean!){topProducts{name...@defer(if:$if,label:\"\"){reviews{author{name}}reviews{author{name}}}}}" + stringValue: "# -\nquery($if:Boolean!){topProducts{name...@defer(if:$if){reviews{author{name}}reviews{author{name}}}}}" - key: apollo_private.query.aliases value: intValue: 0 diff --git a/apollo-router/tests/snapshots/apollo_reports__condition_else-2.snap b/apollo-router/tests/snapshots/apollo_reports__condition_else-2.snap index cae3641fd5..8fd3f3243e 100644 --- a/apollo-router/tests/snapshots/apollo_reports__condition_else-2.snap +++ b/apollo-router/tests/snapshots/apollo_reports__condition_else-2.snap @@ -11,7 +11,7 @@ header: uname: "[uname]" executable_schema_id: "[executable_schema_id]" traces_per_query: - "# -\nquery($if:Boolean!){topProducts{name...@defer(if:$if,label:\"\"){reviews{author{name}}reviews{author{name}}}}}": + "# -\nquery($if:Boolean!){topProducts{name...@defer(if:$if){reviews{author{name}}reviews{author{name}}}}}": trace: - start_time: seconds: "[seconds]" diff --git a/apollo-router/tests/snapshots/apollo_reports__condition_else.snap b/apollo-router/tests/snapshots/apollo_reports__condition_else.snap index cae3641fd5..8fd3f3243e 100644 --- a/apollo-router/tests/snapshots/apollo_reports__condition_else.snap +++ b/apollo-router/tests/snapshots/apollo_reports__condition_else.snap @@ -11,7 +11,7 @@ header: uname: "[uname]" executable_schema_id: "[executable_schema_id]" traces_per_query: - "# -\nquery($if:Boolean!){topProducts{name...@defer(if:$if,label:\"\"){reviews{author{name}}reviews{author{name}}}}}": + "# -\nquery($if:Boolean!){topProducts{name...@defer(if:$if){reviews{author{name}}reviews{author{name}}}}}": trace: - start_time: seconds: "[seconds]" diff --git a/apollo-router/tests/snapshots/apollo_reports__condition_if-2.snap b/apollo-router/tests/snapshots/apollo_reports__condition_if-2.snap index b9d955ee9c..282dbbb14d 100644 --- a/apollo-router/tests/snapshots/apollo_reports__condition_if-2.snap +++ b/apollo-router/tests/snapshots/apollo_reports__condition_if-2.snap @@ -11,7 +11,7 @@ header: uname: "[uname]" executable_schema_id: "[executable_schema_id]" traces_per_query: - "# -\nquery($if:Boolean!){topProducts{name...@defer(if:$if,label:\"\"){reviews{author{name}}reviews{author{name}}}}}": + "# -\nquery($if:Boolean!){topProducts{name...@defer(if:$if){reviews{author{name}}reviews{author{name}}}}}": trace: - start_time: seconds: "[seconds]" diff --git a/apollo-router/tests/snapshots/apollo_reports__condition_if.snap b/apollo-router/tests/snapshots/apollo_reports__condition_if.snap index b9d955ee9c..282dbbb14d 100644 --- a/apollo-router/tests/snapshots/apollo_reports__condition_if.snap +++ b/apollo-router/tests/snapshots/apollo_reports__condition_if.snap @@ -11,7 +11,7 @@ header: uname: "[uname]" executable_schema_id: "[executable_schema_id]" traces_per_query: - "# -\nquery($if:Boolean!){topProducts{name...@defer(if:$if,label:\"\"){reviews{author{name}}reviews{author{name}}}}}": + "# -\nquery($if:Boolean!){topProducts{name...@defer(if:$if){reviews{author{name}}reviews{author{name}}}}}": trace: - start_time: seconds: "[seconds]" From d6135f69b55f61e67f56f1838820f770113ffceb Mon Sep 17 00:00:00 2001 From: Geoffroy Couprie Date: Fri, 15 Nov 2024 11:02:44 +0100 Subject: [PATCH 40/77] Fix introspection query deduplication (#6257) Introspection queries are not supposed to be cached, but their result still needs to be sent to deduplicated queries. This also fixes a case where errors returned by `poll_ready` were not sent to deduplicated queries --- .../fix_geal_introspection_dedup_fix.md | 5 +++++ .../src/query_planner/caching_query_planner.rs | 18 +++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 .changesets/fix_geal_introspection_dedup_fix.md diff --git a/.changesets/fix_geal_introspection_dedup_fix.md b/.changesets/fix_geal_introspection_dedup_fix.md new file mode 100644 index 0000000000..f93112b815 --- /dev/null +++ b/.changesets/fix_geal_introspection_dedup_fix.md @@ -0,0 +1,5 @@ +### Fix introspection query deduplication ([Issue #6249](https://github.com/apollographql/router/issues/6249)) + +To reduce CPU usage, query planning and introspection queries are deduplicated. In some cases, deduplicated introspection queries were not receiving their result. This makes sure that answers are sent in all cases. + +By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/6257 \ No newline at end of file diff --git a/apollo-router/src/query_planner/caching_query_planner.rs b/apollo-router/src/query_planner/caching_query_planner.rs index ba65ba52a6..ee5db8dccb 100644 --- a/apollo-router/src/query_planner/caching_query_planner.rs +++ b/apollo-router/src/query_planner/caching_query_planner.rs @@ -518,7 +518,19 @@ where // of restarting the query planner until another timeout tokio::task::spawn( async move { - let res = self.delegate.ready().await?.call(request).await; + let service = match self.delegate.ready().await { + Ok(service) => service, + Err(error) => { + let e = Arc::new(error); + let err = e.clone(); + tokio::spawn(async move { + entry.insert(Err(err)).await; + }); + return Err(CacheResolverError::RetrievalError(e)); + } + }; + + let res = service.call(request).await; match res { Ok(QueryPlannerResponse { content, errors }) => { @@ -536,6 +548,10 @@ where tokio::spawn(async move { entry.insert(Ok(content)).await; }); + } else { + tokio::spawn(async move { + entry.send(Ok(content)).await; + }); } } From e8d32d6d281955ac7564f6bb2c1e0fdbcd82d77c Mon Sep 17 00:00:00 2001 From: Taylor Ninesling Date: Fri, 15 Nov 2024 10:06:45 -0800 Subject: [PATCH 41/77] Do not override concrete type names with interface names when merging responses (#6250) Co-authored-by: Iryna Shestak --- .../fix_tninesling_typename_resolution.md | 5 + apollo-router/src/json_ext.rs | 113 ++++++++++++++++++ apollo-router/src/query_planner/execution.rs | 18 +-- apollo-router/src/query_planner/selection.rs | 2 +- 4 files changed, 128 insertions(+), 10 deletions(-) create mode 100644 .changesets/fix_tninesling_typename_resolution.md diff --git a/.changesets/fix_tninesling_typename_resolution.md b/.changesets/fix_tninesling_typename_resolution.md new file mode 100644 index 0000000000..934d4ed5d2 --- /dev/null +++ b/.changesets/fix_tninesling_typename_resolution.md @@ -0,0 +1,5 @@ +### Do not override concrete type names with interface names when merging responses ([PR #6250](https://github.com/apollographql/router/pull/6250)) + +When using `@interfaceObject`, differing pieces of data can come back with either concrete types or interface types depending on the source. To make the response merging order-agnostic, check the schema to ensure concrete types are not overwritten with interfaces or less specific types. + +By [@tninesling](https://github.com/tninesling) in https://github.com/apollographql/router/pull/6250 diff --git a/apollo-router/src/json_ext.rs b/apollo-router/src/json_ext.rs index 54d1dd0bfe..9bc94833d0 100644 --- a/apollo-router/src/json_ext.rs +++ b/apollo-router/src/json_ext.rs @@ -72,6 +72,12 @@ pub(crate) trait ValueExt { #[track_caller] fn deep_merge(&mut self, other: Self); + /// Deep merge two JSON objects, overwriting values in `self` if it has the same key as `other`. + /// For GraphQL response objects, this uses schema information to avoid overwriting a concrete + /// `__typename` with an interface name. + #[track_caller] + fn type_aware_deep_merge(&mut self, other: Self, schema: &Schema); + /// Returns `true` if the values are equal and the objects are ordered the same. /// /// **Note:** this is recursive. @@ -192,6 +198,53 @@ impl ValueExt for Value { } } + fn type_aware_deep_merge(&mut self, other: Self, schema: &Schema) { + match (self, other) { + (Value::Object(a), Value::Object(b)) => { + for (key, value) in b.into_iter() { + let k = key.clone(); + match a.entry(key) { + Entry::Vacant(e) => { + e.insert(value); + } + Entry::Occupied(e) => match (e.into_mut(), value) { + (Value::String(type1), Value::String(type2)) + if k.as_str() == TYPENAME => + { + // If type1 is a subtype of type2, we skip this overwrite to preserve the more specific `__typename` + // in the response. Ideally, we could use `Schema::is_implementation`, but that looks to be buggy + // and does not catch the problem we are trying to resolve. + if !schema.is_subtype(type2.as_str(), type1.as_str()) { + *type1 = type2; + } + } + (t, s) => t.type_aware_deep_merge(s, schema), + }, + } + } + } + (Value::Array(a), Value::Array(mut b)) => { + for (b_value, a_value) in b.drain(..min(a.len(), b.len())).zip(a.iter_mut()) { + a_value.type_aware_deep_merge(b_value, schema); + } + + a.extend(b); + } + (_, Value::Null) => {} + (Value::Object(_), Value::Array(_)) => { + failfast_debug!("trying to replace an object with an array"); + } + (Value::Array(_), Value::Object(_)) => { + failfast_debug!("trying to replace an array with an object"); + } + (a, b) => { + if b != Value::Null { + *a = b; + } + } + } + } + #[cfg(test)] fn eq_and_ordered(&self, other: &Self) -> bool { match (self, other) { @@ -1333,6 +1386,66 @@ mod tests { ); } + #[test] + fn interface_typename_merging() { + let schema = Schema::parse( + r#" + schema + @link(url: "https://specs.apollo.dev/link/v1.0") + @link(url: "https://specs.apollo.dev/join/v0.3", for: EXECUTION) + { + query: Query + } + directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA + directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true, isInterfaceObject: Boolean! = false) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + directive @join__graph(name: String!, url: String!) on ENUM_VALUE + + scalar link__Import + scalar join__FieldSet + + enum link__Purpose { + SECURITY + EXECUTION + } + + enum join__Graph { + TEST @join__graph(name: "test", url: "http://localhost:4001/graphql") + } + + interface I { + s: String + } + + type C implements I { + s: String + } + + type Query { + i: I + } + "#, + &Default::default(), + ) + .expect("valid schema"); + let mut response1 = json!({ + "__typename": "C" + }); + let response2 = json!({ + "__typename": "I", + "s": "data" + }); + + response1.type_aware_deep_merge(response2, &schema); + + assert_eq!( + response1, + json!({ + "__typename": "C", + "s": "data" + }) + ); + } + #[test] fn test_is_subset_eq() { assert_is_subset!( diff --git a/apollo-router/src/query_planner/execution.rs b/apollo-router/src/query_planner/execution.rs index a4e58f82a0..bd23f549ea 100644 --- a/apollo-router/src/query_planner/execution.rs +++ b/apollo-router/src/query_planner/execution.rs @@ -139,7 +139,7 @@ impl PlanNode { ) .in_current_span() .await; - value.deep_merge(v); + value.type_aware_deep_merge(v, parameters.schema); errors.extend(err.into_iter()); } } @@ -167,7 +167,7 @@ impl PlanNode { .collect(); while let Some((v, err)) = stream.next().in_current_span().await { - value.deep_merge(v); + value.type_aware_deep_merge(v, parameters.schema); errors.extend(err.into_iter()); } } @@ -305,7 +305,7 @@ impl PlanNode { "otel.kind" = "INTERNAL" )) .await; - value.deep_merge(v); + value.type_aware_deep_merge(v, parameters.schema); errors.extend(err.into_iter()); let _ = primary_sender.send((value.clone(), errors.clone())); @@ -353,7 +353,7 @@ impl PlanNode { "otel.kind" = "INTERNAL" )) .await; - value.deep_merge(v); + value.type_aware_deep_merge(v, parameters.schema); errors.extend(err.into_iter()); } else if current_dir.is_empty() { // If the condition is on the root selection set and it's the only one @@ -373,7 +373,7 @@ impl PlanNode { "otel.kind" = "INTERNAL" )) .await; - value.deep_merge(v); + value.type_aware_deep_merge(v, parameters.schema); errors.extend(err.into_iter()); } else if current_dir.is_empty() { // If the condition is on the root selection set and it's the only one @@ -451,7 +451,7 @@ impl DeferredNode { if is_depends_empty { let (primary_value, primary_errors) = primary_receiver.recv().await.unwrap_or_default(); - value.deep_merge(primary_value); + value.type_aware_deep_merge(primary_value, &sc); errors.extend(primary_errors) } else { while let Some((v, _remaining)) = stream.next().await { @@ -460,7 +460,7 @@ impl DeferredNode { // or because it is lagging, but here we only send one message so it // will not happen if let Some(Ok((deferred_value, err))) = v { - value.deep_merge(deferred_value); + value.type_aware_deep_merge(deferred_value, &sc); errors.extend(err.into_iter()) } } @@ -499,7 +499,7 @@ impl DeferredNode { if !is_depends_empty { let (primary_value, primary_errors) = primary_receiver.recv().await.unwrap_or_default(); - v.deep_merge(primary_value); + v.type_aware_deep_merge(primary_value, &sc); errors.extend(primary_errors) } @@ -524,7 +524,7 @@ impl DeferredNode { } else { let (primary_value, primary_errors) = primary_receiver.recv().await.unwrap_or_default(); - value.deep_merge(primary_value); + value.type_aware_deep_merge(primary_value, &sc); errors.extend(primary_errors); if let Err(e) = tx diff --git a/apollo-router/src/query_planner/selection.rs b/apollo-router/src/query_planner/selection.rs index 629b678347..cf58be1244 100644 --- a/apollo-router/src/query_planner/selection.rs +++ b/apollo-router/src/query_planner/selection.rs @@ -175,7 +175,7 @@ pub(crate) fn execute_selection_set<'a>( e.insert(value); } Entry::Occupied(e) => { - e.into_mut().deep_merge(value); + e.into_mut().type_aware_deep_merge(value, schema); } } } From 0bdea7eaa40dc21cec727e9cf7d3d5c84e4619b7 Mon Sep 17 00:00:00 2001 From: Duckki Oe Date: Sat, 16 Nov 2024 20:28:15 -0800 Subject: [PATCH 42/77] fix(dual-query-planner): semantic diff treatment to subscription comparison (#6266) --- .../src/query_planner/dual_query_planner.rs | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/apollo-router/src/query_planner/dual_query_planner.rs b/apollo-router/src/query_planner/dual_query_planner.rs index 5c0f41846f..6b409b44ae 100644 --- a/apollo-router/src/query_planner/dual_query_planner.rs +++ b/apollo-router/src/query_planner/dual_query_planner.rs @@ -279,23 +279,26 @@ fn fetch_node_matches(this: &FetchNode, other: &FetchNode) -> Result<(), MatchFa Ok(()) } -fn subscription_primary_matches(this: &SubscriptionNode, other: &SubscriptionNode) -> bool { +fn subscription_primary_matches( + this: &SubscriptionNode, + other: &SubscriptionNode, +) -> Result<(), MatchFailure> { let SubscriptionNode { service_name, variable_usages, operation, - operation_name, + operation_name: _, // ignored (reordered parallel fetches may have different names) operation_kind, input_rewrites, output_rewrites, } = this; - *service_name == other.service_name - && *variable_usages == other.variable_usages - && *operation_name == other.operation_name - && *operation_kind == other.operation_kind - && *input_rewrites == other.input_rewrites - && *output_rewrites == other.output_rewrites - && operation_matches(operation, &other.operation).is_ok() + check_match_eq!(*service_name, other.service_name); + check_match_eq!(*operation_kind, other.operation_kind); + check_match!(vec_matches_sorted(variable_usages, &other.variable_usages)); + check_match!(same_rewrites(input_rewrites, &other.input_rewrites)); + check_match!(same_rewrites(output_rewrites, &other.output_rewrites)); + operation_matches(operation, &other.operation)?; + Ok(()) } fn operation_matches( @@ -647,7 +650,7 @@ fn plan_node_matches(this: &PlanNode, other: &PlanNode) -> Result<(), MatchFailu rest: other_rest, }, ) => { - check_match!(subscription_primary_matches(primary, other_primary)); + subscription_primary_matches(primary, other_primary)?; opt_plan_node_matches(rest, other_rest) .map_err(|err| err.add_description("under Subscription"))?; } From c3b8637e1908487dee80d007ed4cb2f77002ea27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e?= Date: Mon, 18 Nov 2024 17:05:16 +0000 Subject: [PATCH 43/77] Report a metric to Apollo if fragment reuse is enabled (#6267) Co-authored-by: Bryn Cooke --- apollo-router/src/configuration/metrics.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/apollo-router/src/configuration/metrics.rs b/apollo-router/src/configuration/metrics.rs index 0020b20935..52ec64b384 100644 --- a/apollo-router/src/configuration/metrics.rs +++ b/apollo-router/src/configuration/metrics.rs @@ -49,6 +49,8 @@ impl Metrics { data.populate_user_plugins_instrument(configuration); data.populate_query_planner_experimental_parallelism(configuration); data.populate_deno_or_rust_mode_instruments(configuration); + data.populate_legacy_fragment_usage(configuration); + data.into() } } @@ -494,6 +496,18 @@ impl InstrumentData { ); } + pub(crate) fn populate_legacy_fragment_usage(&mut self, configuration: &Configuration) { + // Fragment generation takes precedence over fragment reuse. Only report when fragment reuse is *actually active*. + if configuration.supergraph.reuse_query_fragments == Some(true) + && !configuration.supergraph.generate_query_fragments + { + self.data.insert( + "apollo.router.config.reuse_query_fragments".to_string(), + (1, HashMap::new()), + ); + } + } + pub(crate) fn populate_query_planner_experimental_parallelism( &mut self, configuration: &Configuration, From d2365a911e7b07703cf8a16fc40f967bd68815ec Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Tue, 19 Nov 2024 11:30:22 +0200 Subject: [PATCH 44/77] Configuration Options for HTTP/1 Max Headers and Buffer Limits (#6194) Co-authored-by: Jesse Rosenberger Co-authored-by: Ivan Goncharov Co-authored-by: Simon Sapin --- .changesets/feat_max_headers.md | 19 +++ .circleci/config.yml | 8 +- Cargo.lock | 6 +- Cargo.toml | 3 + apollo-router/Cargo.toml | 6 +- .../axum_factory/axum_http_server_factory.rs | 16 ++ apollo-router/src/axum_factory/listeners.rs | 15 +- apollo-router/src/configuration/mod.rs | 8 + ...nfiguration__tests__schema_generation.snap | 15 ++ apollo-router/src/configuration/tests.rs | 5 + apollo-router/src/plugins/limits/mod.rs | 16 ++ apollo-router/tests/integration/mod.rs | 1 + apollo-router/tests/integration/supergraph.rs | 140 ++++++++++++++++++ .../source/reference/router/configuration.mdx | 20 +++ .../routing/security/request-limits.mdx | 20 +++ xtask/src/commands/dist.rs | 16 +- 16 files changed, 294 insertions(+), 20 deletions(-) create mode 100644 .changesets/feat_max_headers.md create mode 100644 apollo-router/tests/integration/supergraph.rs diff --git a/.changesets/feat_max_headers.md b/.changesets/feat_max_headers.md new file mode 100644 index 0000000000..30939d802a --- /dev/null +++ b/.changesets/feat_max_headers.md @@ -0,0 +1,19 @@ +### Configuration Options for HTTP/1 Max Headers and Buffer Limits ([PR #6194](https://github.com/apollographql/router/pull/6194)) + +This update introduces configuration options that allow you to adjust the maximum number of HTTP/1 request headers and the maximum buffer size allocated for headers. + +By default, the Router accepts HTTP/1 requests with up to 100 headers and allocates ~400kib of buffer space to store them. If you need to handle requests with more headers or require a different buffer size, you can now configure these limits in the Router's configuration file: +```yaml +limits: + http1_request_max_headers: 200 + http1_request_max_buf_size: 200kib +``` + +Note for Rust Crate Users: If you are using the Router as a Rust crate, the `http1_request_max_buf_size` option requires the `hyper_header_limits` feature and also necessitates using Apollo's fork of the Hyper crate until the [changes are merged upstream](https://github.com/hyperium/hyper/pull/3523). +You can include this fork by adding the following patch to your Cargo.toml file: +```toml +[patch.crates-io] +"hyper" = { git = "https://github.com/apollographql/hyper.git", tag = "header-customizations-20241108" } +``` + +By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6194 diff --git a/.circleci/config.yml b/.circleci/config.yml index 91bce18b05..7b932c7fc3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -507,7 +507,7 @@ commands: # TODO: remove this workaround once we update to Xcode >= 15.1.0 # See: https://github.com/apollographql/router/pull/5462 RUST_LIB_BACKTRACE: 0 - command: xtask test --workspace --locked --features ci + command: xtask test --workspace --locked --features ci,hyper_header_limits - run: name: Delete large files from cache command: | @@ -655,10 +655,10 @@ jobs: - run: cargo xtask release prepare nightly - run: command: > - cargo xtask dist --target aarch64-apple-darwin + cargo xtask dist --target aarch64-apple-darwin --features hyper_header_limits - run: command: > - cargo xtask dist --target x86_64-apple-darwin + cargo xtask dist --target x86_64-apple-darwin --features hyper_header_limits - run: command: > mkdir -p artifacts @@ -718,7 +718,7 @@ jobs: - run: cargo xtask release prepare nightly - run: command: > - cargo xtask dist + cargo xtask dist --features hyper_header_limits - run: command: > mkdir -p artifacts diff --git a/Cargo.lock b/Cargo.lock index 192ac8fc00..b8d2d105bd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3382,9 +3382,8 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +version = "0.14.31" +source = "git+https://github.com/apollographql/hyper.git?tag=header-customizations-20241108#c42aec785394b40645a283384838b856beace011" dependencies = [ "bytes", "futures-channel", @@ -3397,6 +3396,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", + "smallvec", "socket2 0.5.7", "tokio", "tower-service", diff --git a/Cargo.toml b/Cargo.toml index d8514547c6..c492b05480 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,3 +76,6 @@ sha1 = "0.10.6" tempfile = "3.10.1" tokio = { version = "1.36.0", features = ["full"] } tower = { version = "0.4.13", features = ["full"] } + +[patch.crates-io] +"hyper" = { git = "https://github.com/apollographql/hyper.git", tag = "header-customizations-20241108" } diff --git a/apollo-router/Cargo.toml b/apollo-router/Cargo.toml index ced84ad29f..6c7e06a6d0 100644 --- a/apollo-router/Cargo.toml +++ b/apollo-router/Cargo.toml @@ -52,6 +52,10 @@ docs_rs = ["router-bridge/docs_rs"] # and not yet ready for production use. telemetry_next = [] +# Allow Router to use feature from custom fork of Hyper until it is merged: +# https://github.com/hyperium/hyper/pull/3523 +hyper_header_limits = [] + # is set when ci builds take place. It allows us to disable some tests when CI is running on certain platforms. ci = [] @@ -105,7 +109,7 @@ http-body = "0.4.6" heck = "0.5.0" humantime = "2.1.0" humantime-serde = "1.1.1" -hyper = { version = "0.14.28", features = ["server", "client", "stream"] } +hyper = { version = "0.14.31", features = ["server", "client", "stream"] } hyper-rustls = { version = "0.24.2", features = ["http1", "http2"] } indexmap = { version = "2.2.6", features = ["serde"] } itertools = "0.13.0" diff --git a/apollo-router/src/axum_factory/axum_http_server_factory.rs b/apollo-router/src/axum_factory/axum_http_server_factory.rs index 08df933dc6..391424f0b1 100644 --- a/apollo-router/src/axum_factory/axum_http_server_factory.rs +++ b/apollo-router/src/axum_factory/axum_http_server_factory.rs @@ -5,6 +5,7 @@ use std::sync::atomic::AtomicBool; use std::sync::atomic::AtomicU64; use std::sync::atomic::Ordering; use std::sync::Arc; +use std::time::Duration; use std::time::Instant; use axum::error_handling::HandleErrorLayer; @@ -24,6 +25,7 @@ use http::header::CONTENT_ENCODING; use http::HeaderValue; use http::Request; use http_body::combinators::UnsyncBoxBody; +use hyper::server::conn::Http; use hyper::Body; use itertools::Itertools; use multimap::MultiMap; @@ -298,12 +300,25 @@ impl HttpServerFactory for AxumHttpServerFactory { let actual_main_listen_address = main_listener .local_addr() .map_err(ApolloRouterError::ServerCreationError)?; + let mut http_config = Http::new(); + http_config.http1_keep_alive(true); + http_config.http1_header_read_timeout(Duration::from_secs(10)); + + #[cfg(feature = "hyper_header_limits")] + if let Some(max_headers) = configuration.limits.http1_max_request_headers { + http_config.http1_max_headers(max_headers); + } + + if let Some(max_buf_size) = configuration.limits.http1_max_request_buf_size { + http_config.max_buf_size(max_buf_size.as_u64() as usize); + } let (main_server, main_shutdown_sender) = serve_router_on_listen_addr( main_listener, actual_main_listen_address.clone(), all_routers.main.1, true, + http_config.clone(), all_connections_stopped_sender.clone(), ); @@ -343,6 +358,7 @@ impl HttpServerFactory for AxumHttpServerFactory { listen_addr.clone(), router, false, + http_config.clone(), all_connections_stopped_sender.clone(), ); ( diff --git a/apollo-router/src/axum_factory/listeners.rs b/apollo-router/src/axum_factory/listeners.rs index dad439317c..52ea352979 100644 --- a/apollo-router/src/axum_factory/listeners.rs +++ b/apollo-router/src/axum_factory/listeners.rs @@ -202,6 +202,7 @@ pub(super) fn serve_router_on_listen_addr( address: ListenAddr, router: axum::Router, main_graphql_port: bool, + http_config: Http, all_connections_stopped_sender: mpsc::Sender<()>, ) -> (impl Future, oneshot::Sender<()>) { let (shutdown_sender, shutdown_receiver) = oneshot::channel::<()>(); @@ -243,6 +244,7 @@ pub(super) fn serve_router_on_listen_addr( } let address = address.clone(); + let mut http_config = http_config.clone(); tokio::task::spawn(async move { // this sender must be moved into the session to track that it is still running let _connection_stop_signal = connection_stop_signal; @@ -261,11 +263,8 @@ pub(super) fn serve_router_on_listen_addr( .expect( "this should not fail unless the socket is invalid", ); - let connection = Http::new() - .http1_keep_alive(true) - .http1_header_read_timeout(Duration::from_secs(10)) - .serve_connection(stream, app); + let connection = http_config.serve_connection(stream, app); tokio::pin!(connection); tokio::select! { // the connection finished first @@ -291,9 +290,7 @@ pub(super) fn serve_router_on_listen_addr( NetworkStream::Unix(stream) => { let received_first_request = Arc::new(AtomicBool::new(false)); let app = IdleConnectionChecker::new(received_first_request.clone(), app); - let connection = Http::new() - .http1_keep_alive(true) - .serve_connection(stream, app); + let connection = http_config.serve_connection(stream, app); tokio::pin!(connection); tokio::select! { @@ -329,9 +326,7 @@ pub(super) fn serve_router_on_listen_addr( let protocol = stream.get_ref().1.alpn_protocol(); let http2 = protocol == Some(&b"h2"[..]); - let connection = Http::new() - .http1_keep_alive(true) - .http1_header_read_timeout(Duration::from_secs(10)) + let connection = http_config .http2_only(http2) .serve_connection(stream, app); diff --git a/apollo-router/src/configuration/mod.rs b/apollo-router/src/configuration/mod.rs index c561a131f9..2df5ad8c62 100644 --- a/apollo-router/src/configuration/mod.rs +++ b/apollo-router/src/configuration/mod.rs @@ -492,6 +492,14 @@ impl Configuration { impl Configuration { pub(crate) fn validate(self) -> Result { + #[cfg(not(feature = "hyper_header_limits"))] + if self.limits.http1_max_request_headers.is_some() { + return Err(ConfigurationError::InvalidConfiguration { + message: "'limits.http1_max_request_headers' requires 'hyper_header_limits' feature", + error: "enable 'hyper_header_limits' feature in order to use 'limits.http1_max_request_headers'".to_string(), + }); + } + // Sandbox and Homepage cannot be both enabled if self.sandbox.enabled && self.homepage.enabled { return Err(ConfigurationError::InvalidConfiguration { 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 35913d1ce2..3616c90414 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,6 +1,7 @@ --- source: apollo-router/src/configuration/tests.rs expression: "&schema" +snapshot_kind: text --- { "$schema": "http://json-schema.org/draft-07/schema#", @@ -1317,6 +1318,20 @@ expression: "&schema" "additionalProperties": false, "description": "Configuration for operation limits, parser limits, HTTP limits, etc.", "properties": { + "http1_max_request_buf_size": { + "default": null, + "description": "Limit the maximum buffer size for the HTTP1 connection.\n\nDefault is ~400kib.", + "nullable": true, + "type": "string" + }, + "http1_max_request_headers": { + "default": null, + "description": "Limit the maximum number of headers of incoming HTTP1 requests. Default is 100.\n\nIf router receives more headers than the buffer size, it responds to the client with \"431 Request Header Fields Too Large\".", + "format": "uint", + "minimum": 0.0, + "nullable": true, + "type": "integer" + }, "http_max_request_bytes": { "default": 2000000, "description": "Limit the size of incoming HTTP requests read from the network, to protect against running out of memory. Default: 2000000 (2 MB)", diff --git a/apollo-router/src/configuration/tests.rs b/apollo-router/src/configuration/tests.rs index fb7acabf04..21cb5fdb50 100644 --- a/apollo-router/src/configuration/tests.rs +++ b/apollo-router/src/configuration/tests.rs @@ -413,6 +413,11 @@ fn validate_project_config_files() { }; for yaml in yamls { + #[cfg(not(feature = "hyper_header_limits"))] + if yaml.contains("http1_max_request_headers") { + continue; + } + if let Err(e) = validate_yaml_configuration( &yaml, Expansion::default().unwrap(), diff --git a/apollo-router/src/plugins/limits/mod.rs b/apollo-router/src/plugins/limits/mod.rs index ea743c6d2b..ec041a1c02 100644 --- a/apollo-router/src/plugins/limits/mod.rs +++ b/apollo-router/src/plugins/limits/mod.rs @@ -4,6 +4,7 @@ mod limited; use std::error::Error; use async_trait::async_trait; +use bytesize::ByteSize; use http::StatusCode; use schemars::JsonSchema; use serde::Deserialize; @@ -101,6 +102,19 @@ pub(crate) struct Config { /// Limit the size of incoming HTTP requests read from the network, /// to protect against running out of memory. Default: 2000000 (2 MB) pub(crate) http_max_request_bytes: usize, + + /// Limit the maximum number of headers of incoming HTTP1 requests. Default is 100. + /// + /// If router receives more headers than the buffer size, it responds to the client with + /// "431 Request Header Fields Too Large". + /// + pub(crate) http1_max_request_headers: Option, + + /// Limit the maximum buffer size for the HTTP1 connection. + /// + /// Default is ~400kib. + #[schemars(with = "Option", default)] + pub(crate) http1_max_request_buf_size: Option, } impl Default for Config { @@ -113,6 +127,8 @@ impl Default for Config { max_aliases: None, warn_only: false, http_max_request_bytes: 2_000_000, + http1_max_request_headers: None, + http1_max_request_buf_size: None, parser_max_tokens: 15_000, // This is `apollo-parser`โ€™s default, which protects against stack overflow diff --git a/apollo-router/tests/integration/mod.rs b/apollo-router/tests/integration/mod.rs index c383b5348f..7e775a21a9 100644 --- a/apollo-router/tests/integration/mod.rs +++ b/apollo-router/tests/integration/mod.rs @@ -12,6 +12,7 @@ mod operation_limits; mod operation_name; mod query_planner; mod subgraph_response; +mod supergraph; mod traffic_shaping; mod typename; diff --git a/apollo-router/tests/integration/supergraph.rs b/apollo-router/tests/integration/supergraph.rs new file mode 100644 index 0000000000..97d5131d84 --- /dev/null +++ b/apollo-router/tests/integration/supergraph.rs @@ -0,0 +1,140 @@ +use std::collections::HashMap; + +use serde_json::json; +use tower::BoxError; + +use crate::integration::IntegrationTest; + +#[cfg(not(feature = "hyper_header_limits"))] +#[tokio::test(flavor = "multi_thread")] +async fn test_supergraph_error_http1_max_headers_config() -> Result<(), BoxError> { + let mut router = IntegrationTest::builder() + .config( + r#" + limits: + http1_max_request_headers: 100 + "#, + ) + .build() + .await; + + router.start().await; + router.assert_log_contains("'limits.http1_max_request_headers' requires 'hyper_header_limits' feature: enable 'hyper_header_limits' feature in order to use 'limits.http1_max_request_headers'").await; + router.assert_not_started().await; + Ok(()) +} + +#[cfg(feature = "hyper_header_limits")] +#[tokio::test(flavor = "multi_thread")] +async fn test_supergraph_errors_on_http1_max_headers() -> Result<(), BoxError> { + let mut router = IntegrationTest::builder() + .config( + r#" + limits: + http1_max_request_headers: 100 + "#, + ) + .build() + .await; + + router.start().await; + router.assert_started().await; + + let mut headers = HashMap::new(); + for i in 0..100 { + headers.insert(format!("test-header-{i}"), format!("value_{i}")); + } + + let (_trace_id, response) = router + .execute_query_with_headers(&json!({ "query": "{ __typename }"}), headers) + .await; + assert_eq!(response.status(), 431); + Ok(()) +} + +#[cfg(feature = "hyper_header_limits")] +#[tokio::test(flavor = "multi_thread")] +async fn test_supergraph_allow_to_change_http1_max_headers() -> Result<(), BoxError> { + let mut router = IntegrationTest::builder() + .config( + r#" + limits: + http1_max_request_headers: 200 + "#, + ) + .build() + .await; + + router.start().await; + router.assert_started().await; + + let mut headers = HashMap::new(); + for i in 0..100 { + headers.insert(format!("test-header-{i}"), format!("value_{i}")); + } + + let (_trace_id, response) = router + .execute_query_with_headers(&json!({ "query": "{ __typename }"}), headers) + .await; + assert_eq!(response.status(), 200); + assert_eq!( + response.json::().await?, + json!({ "data": { "__typename": "Query" } }) + ); + Ok(()) +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_supergraph_errors_on_http1_header_that_does_not_fit_inside_buffer( +) -> Result<(), BoxError> { + let mut router = IntegrationTest::builder() + .config( + r#" + limits: + http1_max_request_buf_size: 100kib + "#, + ) + .build() + .await; + + router.start().await; + router.assert_started().await; + + let mut headers = HashMap::new(); + headers.insert("test-header".to_string(), "x".repeat(1048576 + 1)); + + let (_trace_id, response) = router + .execute_query_with_headers(&json!({ "query": "{ __typename }"}), headers) + .await; + assert_eq!(response.status(), 431); + Ok(()) +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_supergraph_allow_to_change_http1_max_buf_size() -> Result<(), BoxError> { + let mut router = IntegrationTest::builder() + .config( + r#" + limits: + http1_max_request_buf_size: 2mib + "#, + ) + .build() + .await; + + router.start().await; + router.assert_started().await; + + let mut headers = HashMap::new(); + headers.insert("test-header".to_string(), "x".repeat(1048576 + 1)); + + let (_trace_id, response) = router + .execute_query_with_headers(&json!({ "query": "{ __typename }"}), headers) + .await; + assert_eq!(response.status(), 200); + assert_eq!( + response.json::().await?, + json!({ "data": { "__typename": "Query" } }) + ); + Ok(()) +} diff --git a/docs/source/reference/router/configuration.mdx b/docs/source/reference/router/configuration.mdx index 42597a9e57..9438bb331b 100644 --- a/docs/source/reference/router/configuration.mdx +++ b/docs/source/reference/router/configuration.mdx @@ -1114,6 +1114,8 @@ The router rejects any request that violates at least one of these limits. limits: # Network-based limits http_max_request_bytes: 2000000 # Default value: 2 MB + http1_max_request_headers: 200 # Default value: 100 + http1_max_request_buf_size: 800kib # Default value: 400kib # Parser-based limits parser_max_tokens: 15000 # Default value @@ -1145,6 +1147,24 @@ Before increasing this limit significantly consider testing performance in an environment similar to your production, especially if some clients are untrusted. Many concurrent large requests could cause the router to run out of memory. +##### `http1_max_request_headers` + +Limit the maximum number of headers of incoming HTTP1 requests. +The default value is 100 headers. + +If router receives more headers than the buffer size, it responds to the client with `431 Request Header Fields Too Large`. + +##### `http1_max_request_buf_size` + +Limit the maximum buffer size for the HTTP1 connection. Default is ~400kib. + +Note for Rust Crate Users: If you are using the Router as a Rust crate, the `http1_request_max_buf_size` option requires the `hyper_header_limits` feature and also necessitates using Apollo's fork of the Hyper crate until the [changes are merged upstream](https://github.com/hyperium/hyper/pull/3523). +You can include this fork by adding the following patch to your Cargo.toml file: +```toml +[patch.crates-io] +"hyper" = { git = "https://github.com/apollographql/hyper.git", tag = "header-customizations-20241108" } +``` + #### Parser-based limits ##### `parser_max_tokens` diff --git a/docs/source/routing/security/request-limits.mdx b/docs/source/routing/security/request-limits.mdx index 3cbe0ff552..3feb97f84f 100644 --- a/docs/source/routing/security/request-limits.mdx +++ b/docs/source/routing/security/request-limits.mdx @@ -15,6 +15,8 @@ For enhanced security, the GraphOS Router can reject requests that violate any o limits: # Network-based limits http_max_request_bytes: 2000000 # Default value: 2 MB + http1_max_request_headers: 200 # Default value: 100 + http1_max_request_buf_size: 800kb # Default value: 400kib # Parser-based limits parser_max_tokens: 15000 # Default value @@ -273,6 +275,24 @@ Before increasing this limit significantly consider testing performance in an environment similar to your production, especially if some clients are untrusted. Many concurrent large requests could cause the router to run out of memory. +### `http1_max_request_headers` + +Limit the maximum number of headers of incoming HTTP1 requests. +The default value is 100 headers. + +If router receives more headers than the buffer size, it responds to the client with `431 Request Header Fields Too Large`. + +### `http1_max_request_buf_size` + +Limit the maximum buffer size for the HTTP1 connection. Default is ~400kib. + +Note for Rust Crate Users: If you are using the Router as a Rust crate, the `http1_request_max_buf_size` option requires the `hyper_header_limits` feature and also necessitates using Apollo's fork of the Hyper crate until the [changes are merged upstream](https://github.com/hyperium/hyper/pull/3523). +You can include this fork by adding the following patch to your Cargo.toml file: +```toml +[patch.crates-io] +"hyper" = { git = "https://github.com/apollographql/hyper.git", tag = "header-customizations-20241108" } +``` + ## Parser-based limits ### `parser_max_tokens` diff --git a/xtask/src/commands/dist.rs b/xtask/src/commands/dist.rs index 544b8e9cb7..a28dbe234c 100644 --- a/xtask/src/commands/dist.rs +++ b/xtask/src/commands/dist.rs @@ -5,13 +5,25 @@ use xtask::*; pub struct Dist { #[clap(long)] target: Option, + + /// Pass --features to cargo test + #[clap(long)] + features: Option, } impl Dist { pub fn run(&self) -> Result<()> { + let mut args = vec!["build", "--release"]; + if let Some(features) = &self.features { + args.push("--features"); + args.push(features); + } + match &self.target { Some(target) => { - cargo!(["build", "--release", "--target", target]); + args.push("--target"); + args.push(target); + cargo!(args); let bin_path = TARGET_DIR .join(target.to_string()) @@ -21,7 +33,7 @@ impl Dist { eprintln!("successfully compiled to: {}", &bin_path); } None => { - cargo!(["build", "--release"]); + cargo!(args); let bin_path = TARGET_DIR.join("release").join(RELEASE_BIN); From 2a4d6ff9b02ac0348190357b94bf4dd7170ec31b Mon Sep 17 00:00:00 2001 From: bryn Date: Tue, 19 Nov 2024 10:55:17 +0000 Subject: [PATCH 45/77] Fix header propagation where renames have already taken place #4535 introduced an issue where the following config would not work: ```yaml headers: - propagate: named: a rename: b - propagate: named: a rename: c ``` The existing logic maintained a set of headers that had been propagated already, but did not take into account renaming. It used the original name of the header when tracking which headers had been propagated. This fix adds a test for propagation and fixes the logic to take into account renames. --- .../fix_bryn_fix_header_propagation.md | 18 +++++++ apollo-router/src/plugins/headers.rs | 52 +++++++++++++++++-- 2 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 .changesets/fix_bryn_fix_header_propagation.md diff --git a/.changesets/fix_bryn_fix_header_propagation.md b/.changesets/fix_bryn_fix_header_propagation.md new file mode 100644 index 0000000000..2dabfdbe00 --- /dev/null +++ b/.changesets/fix_bryn_fix_header_propagation.md @@ -0,0 +1,18 @@ +### Fix header propagation where renames have already taken place ([PR #6281](https://github.com/apollographql/router/pull/6281)) + +https://github.com/apollographql/router/pull/4535 introduced a regression where the following header propagation config would not work: + +```yaml +headers: +- propagate: + named: a + rename: b +- propagate: + named: a + rename: c +``` + +The goal of the original PR was to prevent multiple headers from being mapped to a single target header. However, it did not consider renames, and instead prevented multiple mappings from the same source header. +The Router will now propagate headers properly ensuring that a target header is only propagated to once. + +By [@BrynCooke](https://github.com/BrynCooke) in https://github.com/apollographql/router/pull/6281 diff --git a/apollo-router/src/plugins/headers.rs b/apollo-router/src/plugins/headers.rs index c6e0082cfd..b717eef838 100644 --- a/apollo-router/src/plugins/headers.rs +++ b/apollo-router/src/plugins/headers.rs @@ -396,19 +396,20 @@ impl HeadersService { rename, default, }) => { - if !already_propagated.contains(named.as_str()) { + let target_header = rename.as_ref().unwrap_or(named); + if !already_propagated.contains(target_header.as_str()) { let headers = req.subgraph_request.headers_mut(); let values = req.supergraph_request.headers().get_all(named); if values.iter().count() == 0 { if let Some(default) = default { - headers.append(rename.as_ref().unwrap_or(named), default.clone()); + headers.append(target_header, default.clone()); } } else { for value in values { - headers.append(rename.as_ref().unwrap_or(named), value.clone()); + headers.append(target_header, value.clone()); } } - already_propagated.insert(named.as_str()); + already_propagated.insert(target_header.as_str()); } } Operation::Propagate(Propagate::Matching { matching }) => { @@ -787,6 +788,49 @@ mod test { Ok(()) } + #[tokio::test] + async fn test_propagate_multiple() -> Result<(), BoxError> { + let mut mock = MockSubgraphService::new(); + mock.expect_call() + .times(1) + .withf(|request| { + request.assert_headers(vec![ + ("aa", "vaa"), + ("ab", "vab"), + ("ac", "vac"), + ("ra", "vda"), + ("rb", "vda"), + ]) + }) + .returning(example_response); + + let mut service = HeadersLayer::new( + Arc::new(vec![ + Operation::Propagate(Propagate::Named { + named: "da".try_into()?, + rename: Some("ra".try_into()?), + default: None, + }), + Operation::Propagate(Propagate::Named { + named: "da".try_into()?, + rename: Some("rb".try_into()?), + default: None, + }), + // This should not take effect as the header is already propagated + Operation::Propagate(Propagate::Named { + named: "db".try_into()?, + rename: Some("ra".try_into()?), + default: None, + }), + ]), + Arc::new(RESERVED_HEADERS.iter().collect()), + ) + .layer(mock); + + service.ready().await?.call(example_request()).await?; + Ok(()) + } + #[tokio::test] async fn test_propagate_exact_default() -> Result<(), BoxError> { let mut mock = MockSubgraphService::new(); From 8e1928c5d793ef216bc47921ea278ee980e0405b Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 19 Nov 2024 14:52:38 +0100 Subject: [PATCH 46/77] Move heavy computation to a thread pool with a priority queue (#6247) --- .changesets/fix_simon_compute_jobs.md | 24 ++ apollo-router/src/ageing_priority_queue.rs | 147 +++++++++++ apollo-router/src/compute_job.rs | 148 +++++++++++ apollo-router/src/introspection.rs | 4 +- apollo-router/src/lib.rs | 2 + .../src/query_planner/bridge_query_planner.rs | 4 +- .../bridge_query_planner_pool.rs | 249 +++++++++++------- .../src/services/layers/query_analysis.rs | 14 +- apollo-router/src/services/router/service.rs | 5 + .../instrumentation/standard-instruments.mdx | 6 +- 10 files changed, 497 insertions(+), 106 deletions(-) create mode 100644 .changesets/fix_simon_compute_jobs.md create mode 100644 apollo-router/src/ageing_priority_queue.rs create mode 100644 apollo-router/src/compute_job.rs diff --git a/.changesets/fix_simon_compute_jobs.md b/.changesets/fix_simon_compute_jobs.md new file mode 100644 index 0000000000..604f1624c5 --- /dev/null +++ b/.changesets/fix_simon_compute_jobs.md @@ -0,0 +1,24 @@ +### Move heavy computation to a thread pool with a priority queue + +These components can take non-trivial amounts of CPU time: + +* GraphQL parsing +* GraphQL validation +* Query planning +* Schema introspection + +In order to avoid blocking threads that execute asynchronous code, +they are now run (in their respective Rust implementations) +in a new thread pool whose size is based on available CPU cores, +with a priority queue. +Previously we used Tokioโ€™s [`spawn_blocking`] for this purpose, +but it is appears to be intended for blocking I/O +and uses up to 512 threads so it isnโ€™t a great fit for computation tasks. + +`apollo.router.compute_jobs.queued` is a new gauge metric for the number of items in this new queue. +When the new query planner is enabled, the dedicated queue is no longer used +and the `apollo.router.query_planning.queued` metric is no longer emitted. + +[`spawn_blocking`]: https://docs.rs/tokio/latest/tokio/task/fn.spawn_blocking.html + +By [@SimonSapin](https://github.com/SimonSapin) in https://github.com/apollographql/router/pull/6247 diff --git a/apollo-router/src/ageing_priority_queue.rs b/apollo-router/src/ageing_priority_queue.rs new file mode 100644 index 0000000000..d206283093 --- /dev/null +++ b/apollo-router/src/ageing_priority_queue.rs @@ -0,0 +1,147 @@ +use std::sync::atomic::AtomicUsize; +use std::sync::atomic::Ordering; + +/// Items with higher priority value get handled sooner +#[allow(unused)] +pub(crate) enum Priority { + P1 = 1, + P2, + P3, + P4, + P5, + P6, + P7, + P8, +} + +const INNER_QUEUES_COUNT: usize = Priority::P8 as usize - Priority::P1 as usize + 1; + +/// Indices start at 0 for highest priority +const fn index_from_priority(priority: Priority) -> usize { + Priority::P8 as usize - priority as usize +} + +const _: () = { + assert!(index_from_priority(Priority::P1) == 7); + assert!(index_from_priority(Priority::P8) == 0); +}; + +pub(crate) struct AgeingPriorityQueue +where + T: Send + 'static, +{ + /// Items in **lower** indices queues are handled sooner + inner_queues: + [(crossbeam_channel::Sender, crossbeam_channel::Receiver); INNER_QUEUES_COUNT], + queued_count: AtomicUsize, + soft_capacity: usize, +} + +pub(crate) struct Receiver<'a, T> +where + T: Send + 'static, +{ + shared: &'a AgeingPriorityQueue, + select: crossbeam_channel::Select<'a>, +} + +impl AgeingPriorityQueue +where + T: Send + 'static, +{ + pub(crate) fn soft_bounded(soft_capacity: usize) -> Self { + Self { + // Using unbounded channels: callers must use `is_full` to implement backpressure + inner_queues: std::array::from_fn(|_| crossbeam_channel::unbounded()), + queued_count: AtomicUsize::new(0), + soft_capacity, + } + } + + pub(crate) fn queued_count(&self) -> usize { + self.queued_count.load(Ordering::Relaxed) + } + + pub(crate) fn is_full(&self) -> bool { + self.queued_count() >= self.soft_capacity + } + + /// Panics if `priority` is not in `AVAILABLE_PRIORITIES` + pub(crate) fn send(&self, priority: Priority, message: T) { + self.queued_count.fetch_add(1, Ordering::Relaxed); + let (inner_sender, _) = &self.inner_queues[index_from_priority(priority)]; + inner_sender.send(message).expect("disconnected channel") + } + + pub(crate) fn receiver(&self) -> Receiver<'_, T> { + let mut select = crossbeam_channel::Select::new(); + for (_, inner_receiver) in &self.inner_queues { + select.recv(inner_receiver); + } + Receiver { + shared: self, + select, + } + } +} + +impl<'a, T> Receiver<'a, T> +where + T: Send + 'static, +{ + pub(crate) fn blocking_recv(&mut self) -> T { + loop { + // Block until something is ready. + // Ignore the returned index because it is "random" when multiple operations are ready. + self.select.ready(); + // Check inner channels in priority order instead: + for (index, (_, inner_receiver)) in self.shared.inner_queues.iter().enumerate() { + if let Ok(message) = inner_receiver.try_recv() { + self.shared.queued_count.fetch_sub(1, Ordering::Relaxed); + self.age(index); + return message; + } + } + // Another thread raced us to it or `ready()` returned spuriously, try again + } + } + + // Promote some messages from priorities lower (higher indices) than `message_consumed_at_index` + fn age(&self, message_consumed_at_index: usize) { + for window in self.shared.inner_queues[message_consumed_at_index..].windows(2) { + let [higher_priority, lower_priority] = window else { + panic!("expected windows of length 2") + }; + let (higher_priority_sender, _) = higher_priority; + let (_, lower_priority_receiver) = lower_priority; + if let Ok(message) = lower_priority_receiver.try_recv() { + higher_priority_sender + .send(message) + .expect("disconnected channel") + } + } + } +} + +#[test] +fn test_priorities() { + let queue = AgeingPriorityQueue::soft_bounded(3); + assert_eq!(queue.queued_count(), 0); + assert!(!queue.is_full()); + queue.send(Priority::P1, "p1"); + assert!(!queue.is_full()); + queue.send(Priority::P2, "p2"); + assert!(!queue.is_full()); + queue.send(Priority::P3, "p3"); + // The queue is now "full" but sending still works, itโ€™s up to the caller to stop sending + assert!(queue.is_full()); + queue.send(Priority::P2, "p2 again"); + assert_eq!(queue.queued_count(), 4); + + let mut receiver = queue.receiver(); + assert_eq!(receiver.blocking_recv(), "p3"); + assert_eq!(receiver.blocking_recv(), "p2"); + assert_eq!(receiver.blocking_recv(), "p2 again"); + assert_eq!(receiver.blocking_recv(), "p1"); + assert_eq!(queue.queued_count(), 0); +} diff --git a/apollo-router/src/compute_job.rs b/apollo-router/src/compute_job.rs new file mode 100644 index 0000000000..7672dfea83 --- /dev/null +++ b/apollo-router/src/compute_job.rs @@ -0,0 +1,148 @@ +use std::future::Future; +use std::panic::UnwindSafe; +use std::sync::OnceLock; + +use opentelemetry::metrics::MeterProvider as _; +use opentelemetry::metrics::ObservableGauge; +use tokio::sync::oneshot; + +use crate::ageing_priority_queue::AgeingPriorityQueue; +pub(crate) use crate::ageing_priority_queue::Priority; +use crate::metrics::meter_provider; + +/// We generate backpressure in tower `poll_ready` when the number of queued jobs +/// reaches `QUEUE_SOFT_CAPACITY_PER_THREAD * thread_pool_size()` +const QUEUE_SOFT_CAPACITY_PER_THREAD: usize = 20; + +/// Leave a fraction of CPU cores free to run Tokio threads even if this thread pool is very busy: +/// +/// available: 1 pool size: 1 +/// available: 2 pool size: 1 +/// available: 3 pool size: 2 +/// available: 4 pool size: 3 +/// available: 5 pool size: 4 +/// ... +/// available: 8 pool size: 7 +/// available: 9 pool size: 7 +/// ... +/// available: 16 pool size: 14 +/// available: 17 pool size: 14 +/// ... +/// available: 32 pool size: 28 +fn thread_pool_size() -> usize { + let available = std::thread::available_parallelism() + .expect("available_parallelism() failed") + .get(); + thread_poll_size_for_available_parallelism(available) +} + +fn thread_poll_size_for_available_parallelism(available: usize) -> usize { + let reserved = available.div_ceil(8); + (available - reserved).max(1) +} + +type Job = Box; + +fn queue() -> &'static AgeingPriorityQueue { + static QUEUE: OnceLock> = OnceLock::new(); + QUEUE.get_or_init(|| { + let pool_size = thread_pool_size(); + for _ in 0..pool_size { + std::thread::spawn(|| { + // This looks like we need the queue before creating the queue, + // but it happens in a child thread where OnceLock will block + // until `get_or_init` in the parent thread is finished + // and the parent is *not* blocked on the child thread making progress. + let queue = queue(); + + let mut receiver = queue.receiver(); + loop { + let job = receiver.blocking_recv(); + job(); + } + }); + } + AgeingPriorityQueue::soft_bounded(QUEUE_SOFT_CAPACITY_PER_THREAD * pool_size) + }) +} + +/// Returns a future that resolves to a `Result` that is `Ok` if `f` returned or `Err` if it panicked. +pub(crate) fn execute( + priority: Priority, + job: F, +) -> impl Future> +where + F: FnOnce() -> T + Send + UnwindSafe + 'static, + T: Send + 'static, +{ + let (tx, rx) = oneshot::channel(); + let job = Box::new(move || { + // Ignore the error if the oneshot receiver was dropped + let _ = tx.send(std::panic::catch_unwind(job)); + }); + queue().send(priority, job); + async { rx.await.expect("channel disconnected") } +} + +pub(crate) fn is_full() -> bool { + queue().is_full() +} + +pub(crate) fn create_queue_size_gauge() -> ObservableGauge { + meter_provider() + .meter("apollo/router") + .u64_observable_gauge("apollo.router.compute_jobs.queued") + .with_description( + "Number of computation jobs (parsing, planning, โ€ฆ) waiting to be scheduled", + ) + .with_callback(move |m| m.observe(queue().queued_count() as u64, &[])) + .init() +} + +#[cfg(test)] +mod tests { + use std::time::Duration; + use std::time::Instant; + + use super::*; + + #[tokio::test] + async fn test_executes_on_different_thread() { + let test_thread = std::thread::current().id(); + let job_thread = execute(Priority::P4, || std::thread::current().id()) + .await + .unwrap(); + assert_ne!(job_thread, test_thread) + } + + #[tokio::test] + async fn test_parallelism() { + if thread_pool_size() < 2 { + return; + } + let start = Instant::now(); + let one = execute(Priority::P8, || { + std::thread::sleep(Duration::from_millis(1_000)); + 1 + }); + let two = execute(Priority::P8, || { + std::thread::sleep(Duration::from_millis(1_000)); + 1 + 1 + }); + tokio::time::sleep(Duration::from_millis(500)).await; + assert_eq!(one.await.unwrap(), 1); + assert_eq!(two.await.unwrap(), 2); + // Evidence of fearless parallel sleep: + assert!(start.elapsed() < Duration::from_millis(1_400)); + } + + #[test] + fn pool_size() { + assert_eq!(thread_poll_size_for_available_parallelism(1), 1); + assert_eq!(thread_poll_size_for_available_parallelism(2), 1); + assert_eq!(thread_poll_size_for_available_parallelism(3), 2); + assert_eq!(thread_poll_size_for_available_parallelism(4), 3); + assert_eq!(thread_poll_size_for_available_parallelism(31), 27); + assert_eq!(thread_poll_size_for_available_parallelism(32), 28); + } +} diff --git a/apollo-router/src/introspection.rs b/apollo-router/src/introspection.rs index a0a539895d..b69b03c68b 100644 --- a/apollo-router/src/introspection.rs +++ b/apollo-router/src/introspection.rs @@ -6,6 +6,7 @@ use apollo_compiler::executable::Selection; use serde_json_bytes::json; use crate::cache::storage::CacheStorage; +use crate::compute_job; use crate::graphql; use crate::query_planner::QueryKey; use crate::services::layers::query_analysis::ParsedDocument; @@ -130,8 +131,9 @@ impl IntrospectionCache { } let schema = schema.clone(); let doc = doc.clone(); + let priority = compute_job::Priority::P1; // Low priority let response = - tokio::task::spawn_blocking(move || Self::execute_introspection(&schema, &doc)) + compute_job::execute(priority, move || Self::execute_introspection(&schema, &doc)) .await .expect("Introspection panicked"); storage.insert(cache_key, response.clone()).await; diff --git a/apollo-router/src/lib.rs b/apollo-router/src/lib.rs index 9ac39c9e23..6f30ab6239 100644 --- a/apollo-router/src/lib.rs +++ b/apollo-router/src/lib.rs @@ -52,10 +52,12 @@ pub mod plugin; #[macro_use] pub(crate) mod metrics; +mod ageing_priority_queue; mod apollo_studio_interop; pub(crate) mod axum_factory; mod batching; mod cache; +mod compute_job; mod configuration; mod context; mod error; diff --git a/apollo-router/src/query_planner/bridge_query_planner.rs b/apollo-router/src/query_planner/bridge_query_planner.rs index e3cc52dcdd..cc058b5555 100644 --- a/apollo-router/src/query_planner/bridge_query_planner.rs +++ b/apollo-router/src/query_planner/bridge_query_planner.rs @@ -29,6 +29,7 @@ use tower::Service; use super::PlanNode; use super::QueryKey; use crate::apollo_studio_interop::generate_usage_reporting; +use crate::compute_job; use crate::configuration::QueryPlannerMode; use crate::error::PlanErrors; use crate::error::QueryPlannerError; @@ -258,7 +259,8 @@ impl PlannerMode { PlannerMode::Rust(rust_planner) => { let doc = doc.clone(); let rust_planner = rust_planner.clone(); - let (plan, mut root_node) = tokio::task::spawn_blocking(move || { + let priority = compute_job::Priority::P8; // High priority + let (plan, mut root_node) = compute_job::execute(priority, move || { let start = Instant::now(); let query_plan_options = QueryPlanOptions { diff --git a/apollo-router/src/query_planner/bridge_query_planner_pool.rs b/apollo-router/src/query_planner/bridge_query_planner_pool.rs index 652bc997b9..5246b79901 100644 --- a/apollo-router/src/query_planner/bridge_query_planner_pool.rs +++ b/apollo-router/src/query_planner/bridge_query_planner_pool.rs @@ -4,6 +4,7 @@ use std::sync::atomic::AtomicU64; use std::sync::atomic::Ordering; use std::sync::Arc; use std::sync::Mutex; +use std::task::Poll; use std::time::Instant; use apollo_compiler::validation::Valid; @@ -21,6 +22,7 @@ use tower::ServiceExt; use super::bridge_query_planner::BridgeQueryPlanner; use super::QueryPlanResult; +use crate::configuration::QueryPlannerMode; use crate::error::QueryPlannerError; use crate::error::ServiceBuildError; use crate::introspection::IntrospectionCache; @@ -36,13 +38,10 @@ static CHANNEL_SIZE: usize = 1_000; #[derive(Clone)] pub(crate) struct BridgeQueryPlannerPool { js_planners: Vec>>, - sender: Sender<( - QueryPlannerRequest, - oneshot::Sender>, - )>, + pool_mode: PoolMode, schema: Arc, subgraph_schemas: Arc>>>, - pool_size_gauge: Arc>>>, + compute_jobs_queue_size_gauge: Arc>>>, v8_heap_used: Arc, v8_heap_used_gauge: Arc>>>, v8_heap_total: Arc, @@ -50,6 +49,20 @@ pub(crate) struct BridgeQueryPlannerPool { introspection_cache: Arc, } +#[derive(Clone)] +enum PoolMode { + Pool { + sender: Sender<( + QueryPlannerRequest, + oneshot::Sender>, + )>, + pool_size_gauge: Arc>>>, + }, + PassThrough { + delegate: BridgeQueryPlanner, + }, +} + impl BridgeQueryPlannerPool { pub(crate) async fn new( old_js_planners: Vec>>, @@ -59,79 +72,100 @@ impl BridgeQueryPlannerPool { ) -> Result { let rust_planner = PlannerMode::maybe_rust(&schema, &configuration)?; - let mut join_set = JoinSet::new(); - - let (sender, receiver) = bounded::<( - QueryPlannerRequest, - oneshot::Sender>, - )>(CHANNEL_SIZE); - let mut old_js_planners_iterator = old_js_planners.into_iter(); // All query planners in the pool now share the same introspection cache. // This allows meaningful gauges, and it makes sense that queries should be cached across all planners. let introspection_cache = Arc::new(IntrospectionCache::new(&configuration)); - for _ in 0..size.into() { - let schema = schema.clone(); - let configuration = configuration.clone(); - let rust_planner = rust_planner.clone(); - let introspection_cache = introspection_cache.clone(); - + let pool_mode; + let js_planners; + let subgraph_schemas; + if let QueryPlannerMode::New = configuration.experimental_query_planner_mode { let old_planner = old_js_planners_iterator.next(); - join_set.spawn(async move { - BridgeQueryPlanner::new( - schema, - configuration, - old_planner, - rust_planner, - introspection_cache, - ) - .await - }); - } - - let mut bridge_query_planners = Vec::new(); - - while let Some(task_result) = join_set.join_next().await { - let bridge_query_planner = - task_result.map_err(|e| ServiceBuildError::ServiceError(Box::new(e)))??; - bridge_query_planners.push(bridge_query_planner); - } - - let subgraph_schemas = bridge_query_planners - .first() - .ok_or_else(|| { - ServiceBuildError::QueryPlannerError(QueryPlannerError::PoolProcessing( - "There should be at least 1 Query Planner service in pool".to_string(), - )) - })? - .subgraph_schemas(); - - let js_planners: Vec<_> = bridge_query_planners - .iter() - .filter_map(|p| p.js_planner()) - .collect(); - - for mut planner in bridge_query_planners.into_iter() { - let receiver = receiver.clone(); - - tokio::spawn(async move { - while let Ok((request, res_sender)) = receiver.recv().await { - let svc = match planner.ready().await { - Ok(svc) => svc, - Err(e) => { - let _ = res_sender.send(Err(e)); + let delegate = BridgeQueryPlanner::new( + schema.clone(), + configuration, + old_planner, + rust_planner, + introspection_cache.clone(), + ) + .await?; + js_planners = delegate.js_planner().into_iter().collect::>(); + subgraph_schemas = delegate.subgraph_schemas(); + pool_mode = PoolMode::PassThrough { delegate } + } else { + let mut join_set = JoinSet::new(); + let (sender, receiver) = bounded::<( + QueryPlannerRequest, + oneshot::Sender>, + )>(CHANNEL_SIZE); + + for _ in 0..size.into() { + let schema = schema.clone(); + let configuration = configuration.clone(); + let rust_planner = rust_planner.clone(); + let introspection_cache = introspection_cache.clone(); + + let old_planner = old_js_planners_iterator.next(); + join_set.spawn(async move { + BridgeQueryPlanner::new( + schema, + configuration, + old_planner, + rust_planner, + introspection_cache, + ) + .await + }); + } - continue; - } - }; + let mut bridge_query_planners = Vec::new(); - let res = svc.call(request).await; + while let Some(task_result) = join_set.join_next().await { + let bridge_query_planner = + task_result.map_err(|e| ServiceBuildError::ServiceError(Box::new(e)))??; + bridge_query_planners.push(bridge_query_planner); + } - let _ = res_sender.send(res); - } - }); + subgraph_schemas = bridge_query_planners + .first() + .ok_or_else(|| { + ServiceBuildError::QueryPlannerError(QueryPlannerError::PoolProcessing( + "There should be at least 1 Query Planner service in pool".to_string(), + )) + })? + .subgraph_schemas(); + + js_planners = bridge_query_planners + .iter() + .filter_map(|p| p.js_planner()) + .collect(); + + for mut planner in bridge_query_planners.into_iter() { + let receiver = receiver.clone(); + + tokio::spawn(async move { + while let Ok((request, res_sender)) = receiver.recv().await { + let svc = match planner.ready().await { + Ok(svc) => svc, + Err(e) => { + let _ = res_sender.send(Err(e)); + + continue; + } + }; + + let res = svc.call(request).await; + + let _ = res_sender.send(res); + } + }); + } + pool_mode = PoolMode::Pool { + sender, + pool_size_gauge: Default::default(), + } } let v8_heap_used: Arc = Default::default(); let v8_heap_total: Arc = Default::default(); @@ -148,10 +182,10 @@ impl BridgeQueryPlannerPool { Ok(Self { js_planners, - sender, + pool_mode, schema, subgraph_schemas, - pool_size_gauge: Default::default(), + compute_jobs_queue_size_gauge: Default::default(), v8_heap_used, v8_heap_used_gauge: Default::default(), v8_heap_total, @@ -160,15 +194,22 @@ impl BridgeQueryPlannerPool { }) } - fn create_pool_size_gauge(&self) -> ObservableGauge { - let sender = self.sender.clone(); - let meter = meter_provider().meter("apollo/router"); - meter - .u64_observable_gauge("apollo.router.query_planning.queued") - .with_description("Number of queries waiting to be planned") - .with_unit(Unit::new("query")) - .with_callback(move |m| m.observe(sender.len() as u64, &[])) - .init() + fn create_pool_size_gauge(&self) { + if let PoolMode::Pool { + sender, + pool_size_gauge, + } = &self.pool_mode + { + let sender = sender.clone(); + let meter = meter_provider().meter("apollo/router"); + let gauge = meter + .u64_observable_gauge("apollo.router.query_planning.queued") + .with_description("Number of queries waiting to be planned") + .with_unit(Unit::new("query")) + .with_callback(move |m| m.observe(sender.len() as u64, &[])) + .init(); + *pool_size_gauge.lock().expect("lock poisoned") = Some(gauge); + } } fn create_heap_used_gauge(&self) -> ObservableGauge { @@ -228,7 +269,11 @@ impl BridgeQueryPlannerPool { pub(super) fn activate(&self) { // Gauges MUST be initialized after a meter provider is created. // When a hot reload happens this means that the gauges must be re-initialized. - *self.pool_size_gauge.lock().expect("lock poisoned") = Some(self.create_pool_size_gauge()); + *self + .compute_jobs_queue_size_gauge + .lock() + .expect("lock poisoned") = Some(crate::compute_job::create_queue_size_gauge()); + self.create_pool_size_gauge(); *self.v8_heap_used_gauge.lock().expect("lock poisoned") = Some(self.create_heap_used_gauge()); *self.v8_heap_total_gauge.lock().expect("lock poisoned") = @@ -244,22 +289,20 @@ impl tower::Service for BridgeQueryPlannerPool { type Future = BoxFuture<'static, Result>; - fn poll_ready( - &mut self, - _cx: &mut std::task::Context<'_>, - ) -> std::task::Poll> { - if self.sender.is_full() { - std::task::Poll::Ready(Err(QueryPlannerError::PoolProcessing( - "query plan queue is full".into(), - ))) - } else { - std::task::Poll::Ready(Ok(())) + fn poll_ready(&mut self, _cx: &mut std::task::Context<'_>) -> Poll> { + if crate::compute_job::is_full() { + return Poll::Pending; + } + match &self.pool_mode { + PoolMode::Pool { sender, .. } if sender.is_full() => Poll::Ready(Err( + QueryPlannerError::PoolProcessing("query plan queue is full".into()), + )), + _ => Poll::Ready(Ok(())), } } fn call(&mut self, req: QueryPlannerRequest) -> Self::Future { - let (response_sender, response_receiver) = oneshot::channel(); - let sender = self.sender.clone(); + let pool_mode = self.pool_mode.clone(); let get_metrics_future = if let Some(bridge_query_planner) = self.js_planners.first().cloned() { @@ -273,12 +316,22 @@ impl tower::Service for BridgeQueryPlannerPool { }; Box::pin(async move { - let start = Instant::now(); - let _ = sender.send((req, response_sender)).await; - - let res = response_receiver - .await - .map_err(|_| QueryPlannerError::UnhandledPlannerResult)?; + let start; + let res = match pool_mode { + PoolMode::Pool { sender, .. } => { + let (response_sender, response_receiver) = oneshot::channel(); + start = Instant::now(); + let _ = sender.send((req, response_sender)).await; + + response_receiver + .await + .map_err(|_| QueryPlannerError::UnhandledPlannerResult)? + } + PoolMode::PassThrough { mut delegate } => { + start = Instant::now(); + delegate.call(req).await + } + }; f64_histogram!( "apollo.router.query_planning.total.duration", diff --git a/apollo-router/src/services/layers/query_analysis.rs b/apollo-router/src/services/layers/query_analysis.rs index 4af57a5f38..2e2fe77eff 100644 --- a/apollo-router/src/services/layers/query_analysis.rs +++ b/apollo-router/src/services/layers/query_analysis.rs @@ -13,10 +13,10 @@ use http::StatusCode; use lru::LruCache; use router_bridge::planner::UsageReporting; use tokio::sync::Mutex; -use tokio::task; use crate::apollo_studio_interop::generate_extended_references; use crate::apollo_studio_interop::ExtendedReferenceStats; +use crate::compute_job; use crate::context::OPERATION_KIND; use crate::context::OPERATION_NAME; use crate::graphql::Error; @@ -89,7 +89,8 @@ impl QueryAnalysisLayer { // parent let span = tracing::info_span!(QUERY_PARSING_SPAN_NAME, "otel.kind" = "INTERNAL"); - task::spawn_blocking(move || { + let priority = compute_job::Priority::P4; // Medium priority + let job = move || { span.in_scope(|| { Query::parse_document( &query, @@ -98,9 +99,12 @@ impl QueryAnalysisLayer { conf.as_ref(), ) }) - }) - .await - .expect("parse_document task panicked") + }; + // TODO: is this correct? + let job = std::panic::AssertUnwindSafe(job); + compute_job::execute(priority, job) + .await + .expect("Query::parse_document panicked") } pub(crate) async fn supergraph_request( diff --git a/apollo-router/src/services/router/service.rs b/apollo-router/src/services/router/service.rs index 9e379ae3c4..e5792c1a4d 100644 --- a/apollo-router/src/services/router/service.rs +++ b/apollo-router/src/services/router/service.rs @@ -214,6 +214,11 @@ impl Service for RouterService { type Future = BoxFuture<'static, Result>; fn poll_ready(&mut self, _cx: &mut std::task::Context<'_>) -> Poll> { + // This service eventually calls `QueryAnalysisLayer::parse_document()` + // which calls `compute_job::execute()` + if crate::compute_job::is_full() { + return Poll::Pending; + } Poll::Ready(Ok(())) } diff --git a/docs/source/reference/router/telemetry/instrumentation/standard-instruments.mdx b/docs/source/reference/router/telemetry/instrumentation/standard-instruments.mdx index bf0101d802..da9b655036 100644 --- a/docs/source/reference/router/telemetry/instrumentation/standard-instruments.mdx +++ b/docs/source/reference/router/telemetry/instrumentation/standard-instruments.mdx @@ -65,11 +65,15 @@ The coprocessor operations metric has the following attributes: - `apollo_router.query_planning.warmup.duration` - Time spent warming up the query planner queries in seconds. - `apollo.router.query_planning.plan.duration` - Histogram of plan durations isolated to query planning time only. - `apollo.router.query_planning.total.duration` - Histogram of plan durations including queue time. -- `apollo.router.query_planning.queued` - A gauge of the number of queued plans requests. +- `apollo.router.query_planning.queued` - When the legacy planner is used, a gauge of the number of queued plans requests. - `apollo.router.query_planning.plan.evaluated_plans` - Histogram of the number of evaluated query plans. - `apollo.router.v8.heap.used` - heap memory used by V8, in bytes. - `apollo.router.v8.heap.total` - total heap allocated by V8, in bytes. +### Compute jobs + +- `apollo.router.compute_jobs.queued` - A gauge of the number of jobs queued for the thread pool dedicated to CPU-heavy components like GraphQL parsing and validation, and the (new) query planner. + ### Uplink From a33313df8f5fbb003be42309e4c87bfd8a971f5a Mon Sep 17 00:00:00 2001 From: Iryna Shestak Date: Tue, 19 Nov 2024 23:57:23 +0100 Subject: [PATCH 47/77] QP comparison mode: skip comparing PlanNode.authorization (#6287) We are getting mismatches when comparing PlanNodes between JS & Rust with ~authorisation~ authorization directives. This mismatch comes from `authorization` field in PlanNode. The executing query plan (and in comparison mode, it will be the JS QP) receives the appropriate `CacheKeyMetadata`, ```rust CacheKeyMetadata { is_authenticated: true, scopes: [], policies: [] } ``` but the Rust QP does not, since it will not be used to execute, authenticate, etc any of the requests and gets discarded in this comparison mode. Because we do not attach this metadata to the Rust PlanNode **in comparison mode**, we see a ton of false mismatches for everyone using auth directives. This PR skips comparing `authorization` field in PlanNode, as this field gets populated _after_ the query plan is already present. In addition, this data is not based on the query plan itself, so it's not necessary to establish equivalence between the two implementations. When **just the Rust QP is used**, the cache key metadata is present and accounted for correctly, which is why none of the mocks fail when running with only the Rust planner. It's incredibly difficult to write a test for this little nit in semantic equivalence, so this PR does not come with any, apologies. --- .../src/query_planner/dual_query_planner.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/apollo-router/src/query_planner/dual_query_planner.rs b/apollo-router/src/query_planner/dual_query_planner.rs index 6b409b44ae..04d393c2cf 100644 --- a/apollo-router/src/query_planner/dual_query_planner.rs +++ b/apollo-router/src/query_planner/dual_query_planner.rs @@ -256,20 +256,26 @@ fn fetch_node_matches(this: &FetchNode, other: &FetchNode) -> Result<(), MatchFa requires, variable_usages, operation, - operation_name: _, // ignored (reordered parallel fetches may have different names) + // ignored: + // reordered parallel fetches may have different names + operation_name: _, operation_kind, id, input_rewrites, output_rewrites, context_rewrites, - schema_aware_hash: _, // ignored - authorization, + // ignored + schema_aware_hash: _, + // ignored: + // when running in comparison mode, the rust plan node does not have + // the attached cache key metadata for authorisation, since the rust plan is + // not going to be the one being executed. + authorization: _, } = this; check_match_eq!(*service_name, other.service_name); check_match_eq!(*operation_kind, other.operation_kind); check_match_eq!(*id, other.id); - check_match_eq!(*authorization, other.authorization); check_match!(same_requires(requires, &other.requires)); check_match!(vec_matches_sorted(variable_usages, &other.variable_usages)); check_match!(same_rewrites(input_rewrites, &other.input_rewrites)); From ec784f1b118fd5fefe8a2a84bd722cbc1ad77ec5 Mon Sep 17 00:00:00 2001 From: Coenen Benjamin Date: Wed, 20 Nov 2024 10:53:19 +0100 Subject: [PATCH 48/77] add more attributes and include invalidation api endpoint as a root trace to be sampled (#5746) Signed-off-by: Benjamin Coenen <5719034+bnjjj@users.noreply.github.com> --- .../src/plugins/cache/invalidation.rs | 8 ++ .../plugins/cache/invalidation_endpoint.rs | 81 +++++++++++++------ .../src/plugins/telemetry/otel/layer.rs | 2 + 3 files changed, 68 insertions(+), 23 deletions(-) diff --git a/apollo-router/src/plugins/cache/invalidation.rs b/apollo-router/src/plugins/cache/invalidation.rs index 45d623299c..8e30a8a830 100644 --- a/apollo-router/src/plugins/cache/invalidation.rs +++ b/apollo-router/src/plugins/cache/invalidation.rs @@ -259,4 +259,12 @@ impl InvalidationRequest { | InvalidationRequest::Entity { subgraph, .. } => subgraph, } } + + pub(super) fn kind(&self) -> &'static str { + match self { + InvalidationRequest::Subgraph { .. } => "subgraph", + InvalidationRequest::Type { .. } => "type", + InvalidationRequest::Entity { .. } => "entity", + } + } } diff --git a/apollo-router/src/plugins/cache/invalidation_endpoint.rs b/apollo-router/src/plugins/cache/invalidation_endpoint.rs index 0b1af7a9b3..19d4b5a582 100644 --- a/apollo-router/src/plugins/cache/invalidation_endpoint.rs +++ b/apollo-router/src/plugins/cache/invalidation_endpoint.rs @@ -12,6 +12,7 @@ use serde::Serialize; use serde_json_bytes::json; use tower::BoxError; use tower::Service; +use tracing::Span; use tracing_futures::Instrument; use super::entity::Subgraph; @@ -19,10 +20,15 @@ use super::invalidation::Invalidation; use super::invalidation::InvalidationOrigin; use crate::configuration::subgraph::SubgraphConfiguration; use crate::plugins::cache::invalidation::InvalidationRequest; +use crate::plugins::telemetry::consts::OTEL_STATUS_CODE; +use crate::plugins::telemetry::consts::OTEL_STATUS_CODE_ERROR; +use crate::plugins::telemetry::consts::OTEL_STATUS_CODE_OK; use crate::services::router; use crate::services::router::body::RouterBody; use crate::ListenAddr; +pub(crate) const INVALIDATION_ENDPOINT_SPAN_NAME: &str = "invalidation_endpoint"; + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, Default)] #[serde(rename_all = "snake_case", deny_unknown_fields, default)] pub(crate) struct SubgraphInvalidationConfig { @@ -102,6 +108,7 @@ impl Service for InvalidationService { async move { let (parts, body) = req.router_request.into_parts(); if !parts.headers.contains_key(AUTHORIZATION) { + Span::current().record(OTEL_STATUS_CODE, OTEL_STATUS_CODE_ERROR); return Ok(router::Response { response: http::Response::builder() .status(StatusCode::UNAUTHORIZED) @@ -114,6 +121,7 @@ impl Service for InvalidationService { Method::POST => { let body = Into::::into(body) .to_bytes() + .instrument(tracing::info_span!("to_bytes")) .await .map_err(|e| format!("failed to get the request body: {e}")) .and_then(|bytes| { @@ -130,14 +138,26 @@ impl Service for InvalidationService { .headers .get(AUTHORIZATION) .ok_or("cannot find authorization header")? - .to_str()?; + .to_str() + .inspect_err(|_err| { + Span::current().record(OTEL_STATUS_CODE, OTEL_STATUS_CODE_ERROR); + })?; match body { Ok(body) => { + Span::current().record( + "invalidation.request.kinds", + body.iter() + .map(|i| i.kind()) + .collect::>() + .join(", "), + ); let valid_shared_key = body.iter().map(|b| b.subgraph_name()).any(|subgraph_name| { valid_shared_key(&config, shared_key, subgraph_name) }); if !valid_shared_key { + Span::current() + .record(OTEL_STATUS_CODE, OTEL_STATUS_CODE_ERROR); return Ok(router::Response { response: http::Response::builder() .status(StatusCode::UNAUTHORIZED) @@ -148,6 +168,7 @@ impl Service for InvalidationService { } match invalidation .invalidate(InvalidationOrigin::Endpoint, body) + .instrument(tracing::info_span!("invalidate")) .await { Ok(count) => Ok(router::Response { @@ -162,34 +183,48 @@ impl Service for InvalidationService { .map_err(BoxError::from)?, context: req.context, }), - Err(err) => Ok(router::Response { - response: http::Response::builder() - .status(StatusCode::BAD_REQUEST) - .body(err.to_string().into()) - .map_err(BoxError::from)?, - context: req.context, - }), + Err(err) => { + Span::current() + .record(OTEL_STATUS_CODE, OTEL_STATUS_CODE_ERROR); + Ok(router::Response { + response: http::Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(err.to_string().into()) + .map_err(BoxError::from)?, + context: req.context, + }) + } } } - Err(err) => Ok(router::Response { - response: http::Response::builder() - .status(StatusCode::BAD_REQUEST) - .body(err.into()) - .map_err(BoxError::from)?, - context: req.context, - }), + Err(err) => { + Span::current().record(OTEL_STATUS_CODE, OTEL_STATUS_CODE_ERROR); + Ok(router::Response { + response: http::Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(err.into()) + .map_err(BoxError::from)?, + context: req.context, + }) + } } } - _ => Ok(router::Response { - response: http::Response::builder() - .status(StatusCode::METHOD_NOT_ALLOWED) - .body("".into()) - .map_err(BoxError::from)?, - context: req.context, - }), + _ => { + Span::current().record(OTEL_STATUS_CODE, OTEL_STATUS_CODE_ERROR); + Ok(router::Response { + response: http::Response::builder() + .status(StatusCode::METHOD_NOT_ALLOWED) + .body("".into()) + .map_err(BoxError::from)?, + context: req.context, + }) + } } } - .instrument(tracing::info_span!("invalidation_endpoint")), + .instrument(tracing::info_span!( + INVALIDATION_ENDPOINT_SPAN_NAME, + "invalidation.request.kinds" = ::tracing::field::Empty, + "otel.status_code" = OTEL_STATUS_CODE_OK, + )), ) } } diff --git a/apollo-router/src/plugins/telemetry/otel/layer.rs b/apollo-router/src/plugins/telemetry/otel/layer.rs index 866bf50a35..309114b20f 100644 --- a/apollo-router/src/plugins/telemetry/otel/layer.rs +++ b/apollo-router/src/plugins/telemetry/otel/layer.rs @@ -31,6 +31,7 @@ use tracing_subscriber::Layer; use super::OtelData; use super::PreSampledTracer; +use crate::plugins::cache::invalidation_endpoint::INVALIDATION_ENDPOINT_SPAN_NAME; use crate::plugins::telemetry::config::Sampler; use crate::plugins::telemetry::config::SamplerOption; use crate::plugins::telemetry::consts::FIELD_EXCEPTION_MESSAGE; @@ -733,6 +734,7 @@ where if meta.name() != REQUEST_SPAN_NAME && meta.name() != ROUTER_SPAN_NAME && meta.name() != SUBSCRIPTION_EVENT_SPAN_NAME + && meta.name() != INVALIDATION_ENDPOINT_SPAN_NAME { return false; } From 83e6291f2729d3a4388ac1aa452226264cbeddb7 Mon Sep 17 00:00:00 2001 From: Coenen Benjamin Date: Wed, 20 Nov 2024 10:59:29 +0100 Subject: [PATCH 49/77] feat(cache): add support for surrogate cache key (#6234) Signed-off-by: Benjamin <5719034+bnjjj@users.noreply.github.com> Co-authored-by: Jesse Rosenberger --- ...nfiguration__tests__schema_generation.snap | 5 + .../src/plugins/cache/cache_control.rs | 26 ++- apollo-router/src/plugins/cache/entity.rs | 193 ++++++++++++++++++ ...uter__plugins__cache__tests__insert-2.snap | 18 +- ...uter__plugins__cache__tests__insert-3.snap | 18 +- ...uter__plugins__cache__tests__insert-4.snap | 18 +- ...uter__plugins__cache__tests__insert-5.snap | 16 ++ ...uter__plugins__cache__tests__insert-6.snap | 17 ++ ...router__plugins__cache__tests__insert.snap | 17 +- ...ter__plugins__cache__tests__no_data-2.snap | 21 +- ...ter__plugins__cache__tests__no_data-3.snap | 16 ++ ...ter__plugins__cache__tests__no_data-4.snap | 39 ++++ ...outer__plugins__cache__tests__no_data.snap | 28 ++- ...ter__plugins__cache__tests__private-3.snap | 17 +- ...ter__plugins__cache__tests__private-4.snap | 17 ++ ...ter__plugins__cache__tests__private-5.snap | 16 ++ ...ter__plugins__cache__tests__private-6.snap | 9 + ...outer__plugins__cache__tests__private.snap | 25 ++- apollo-router/src/plugins/cache/tests.rs | 81 +++++--- .../routing/performance/caching/entity.mdx | 1 + .../coprocessor-surrogate-cache-key/README.md | 124 +++++++++++ .../nodejs/.gitignore | 2 + .../nodejs/README.md | 16 ++ .../nodejs/package.json | 15 ++ .../nodejs/router.yaml | 36 ++++ .../nodejs/src/index.js | 110 ++++++++++ 26 files changed, 780 insertions(+), 121 deletions(-) create mode 100644 apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__insert-5.snap create mode 100644 apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__insert-6.snap create mode 100644 apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__no_data-3.snap create mode 100644 apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__no_data-4.snap create mode 100644 apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__private-4.snap create mode 100644 apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__private-5.snap create mode 100644 apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__private-6.snap create mode 100644 examples/coprocessor-surrogate-cache-key/README.md create mode 100644 examples/coprocessor-surrogate-cache-key/nodejs/.gitignore create mode 100644 examples/coprocessor-surrogate-cache-key/nodejs/README.md create mode 100644 examples/coprocessor-surrogate-cache-key/nodejs/package.json create mode 100644 examples/coprocessor-surrogate-cache-key/nodejs/router.yaml create mode 100644 examples/coprocessor-surrogate-cache-key/nodejs/src/index.js 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 3616c90414..0dc3c12eab 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 @@ -1701,6 +1701,11 @@ snapshot_kind: text "description": "Enable or disable the entity caching feature", "type": "boolean" }, + "expose_keys_in_context": { + "default": false, + "description": "Expose cache keys in context", + "type": "boolean" + }, "invalidation": { "$ref": "#/definitions/InvalidationEndpointConfig", "description": "#/definitions/InvalidationEndpointConfig", diff --git a/apollo-router/src/plugins/cache/cache_control.rs b/apollo-router/src/plugins/cache/cache_control.rs index dd7d1a598e..4aa300e077 100644 --- a/apollo-router/src/plugins/cache/cache_control.rs +++ b/apollo-router/src/plugins/cache/cache_control.rs @@ -157,7 +157,24 @@ impl CacheControl { Ok(result) } + /// Fill the header map with cache-control header and age header pub(crate) fn to_headers(&self, headers: &mut HeaderMap) -> Result<(), BoxError> { + headers.insert( + CACHE_CONTROL, + HeaderValue::from_str(&self.to_cache_control_header()?)?, + ); + + if let Some(age) = self.age { + if age != 0 { + headers.insert(AGE, age.into()); + } + } + + Ok(()) + } + + /// Only for cache control header and not age + pub(crate) fn to_cache_control_header(&self) -> Result { let mut s = String::new(); let mut prev = false; let now = now_epoch_seconds(); @@ -228,15 +245,8 @@ impl CacheControl { if self.stale_if_error { write!(&mut s, "{}stale-if-error", if prev { "," } else { "" },)?; } - headers.insert(CACHE_CONTROL, HeaderValue::from_str(&s)?); - - if let Some(age) = self.age { - if age != 0 { - headers.insert(AGE, age.into()); - } - } - Ok(()) + Ok(s) } pub(super) fn no_store() -> Self { diff --git a/apollo-router/src/plugins/cache/entity.rs b/apollo-router/src/plugins/cache/entity.rs index b0abd0178e..d50531dde2 100644 --- a/apollo-router/src/plugins/cache/entity.rs +++ b/apollo-router/src/plugins/cache/entity.rs @@ -51,6 +51,7 @@ use crate::plugins::authorization::CacheKeyMetadata; use crate::query_planner::fetch::QueryHash; use crate::query_planner::OperationKind; use crate::services::subgraph; +use crate::services::subgraph::SubgraphRequestId; use crate::services::supergraph; use crate::spec::TYPENAME; use crate::Context; @@ -62,6 +63,8 @@ pub(crate) const ENTITY_CACHE_VERSION: &str = "1.0"; pub(crate) const ENTITIES: &str = "_entities"; pub(crate) const REPRESENTATIONS: &str = "representations"; pub(crate) const CONTEXT_CACHE_KEY: &str = "apollo_entity_cache::key"; +/// Context key to enable support of surrogate cache key +pub(crate) const CONTEXT_CACHE_KEYS: &str = "apollo::entity_cache::cached_keys_status"; register_plugin!("apollo", "preview_entity_cache", EntityCache); @@ -73,6 +76,7 @@ pub(crate) struct EntityCache { entity_type: Option, enabled: bool, metrics: Metrics, + expose_keys_in_context: bool, private_queries: Arc>>, pub(crate) invalidation: Invalidation, } @@ -96,6 +100,10 @@ pub(crate) struct Config { #[serde(default)] enabled: bool, + #[serde(default)] + /// Expose cache keys in context + expose_keys_in_context: bool, + /// Configure invalidation per subgraph subgraph: SubgraphConfiguration, @@ -297,6 +305,7 @@ impl Plugin for EntityCache { storage, entity_type, enabled: init.config.enabled, + expose_keys_in_context: init.config.expose_keys_in_context, endpoint_config: init.config.invalidation.clone().map(Arc::new), subgraphs: Arc::new(init.config.subgraph), metrics: init.config.metrics, @@ -390,6 +399,7 @@ impl Plugin for EntityCache { private_queries, private_id, invalidation: self.invalidation.clone(), + expose_keys_in_context: self.expose_keys_in_context, }))); tower::util::BoxService::new(inner) } else { @@ -467,6 +477,7 @@ impl EntityCache { storage, entity_type: None, enabled: true, + expose_keys_in_context: true, subgraphs: Arc::new(SubgraphConfiguration { all: Subgraph::default(), subgraphs, @@ -496,6 +507,7 @@ struct InnerCacheService { subgraph_ttl: Option, private_queries: Arc>>, private_id: Option, + expose_keys_in_context: bool, invalidation: Invalidation, } @@ -567,6 +579,7 @@ impl InnerCacheService { self.storage.clone(), is_known_private, private_id.as_deref(), + self.expose_keys_in_context, request, ) .instrument(tracing::info_span!("cache.entity.lookup")) @@ -614,6 +627,7 @@ impl InnerCacheService { if private_id.is_none() { // the response has a private scope but we don't have a way to differentiate users, so we do not store the response in cache + // We don't need to fill the context with this cache key as it will never be cached return Ok(response); } } @@ -638,6 +652,7 @@ impl InnerCacheService { &response, cache_control, root_cache_key, + self.expose_keys_in_context, ) .await?; } @@ -663,12 +678,14 @@ impl InnerCacheService { Ok(response) } } else { + let request_id = request.id.clone(); match cache_lookup_entities( self.name.clone(), self.storage.clone(), is_known_private, private_id.as_deref(), request, + self.expose_keys_in_context, ) .instrument(tracing::info_span!("cache.entity.lookup")) .await? @@ -701,6 +718,20 @@ impl InnerCacheService { &[graphql_error], &mut cache_result.0, ); + if self.expose_keys_in_context { + // Update cache keys needed for surrogate cache key because new data has not been fetched + context.upsert::<_, CacheKeysContext>( + CONTEXT_CACHE_KEYS, + |mut value| { + if let Some(cache_keys) = value.get_mut(&request_id) { + cache_keys.retain(|cache_key| { + matches!(cache_key.status, CacheKeyStatus::Cached) + }); + } + value + }, + )?; + } let mut data = Object::default(); data.insert(ENTITIES, new_entities.into()); @@ -727,6 +758,25 @@ impl InnerCacheService { if let Some(control_from_cached) = cache_result.1 { cache_control = cache_control.merge(&control_from_cached); } + if self.expose_keys_in_context { + // Update cache keys needed for surrogate cache key when it's new data and not data from the cache + let response_id = response.id.clone(); + let cache_control_str = cache_control.to_cache_control_header()?; + response.context.upsert::<_, CacheKeysContext>( + CONTEXT_CACHE_KEYS, + |mut value| { + if let Some(cache_keys) = value.get_mut(&response_id) { + for cache_key in cache_keys + .iter_mut() + .filter(|c| matches!(c.status, CacheKeyStatus::New)) + { + cache_key.cache_control = cache_control_str.clone(); + } + } + value + }, + )?; + } if !is_known_private && cache_control.private() { self.private_queries.write().await.insert(query.to_string()); @@ -797,6 +847,7 @@ async fn cache_lookup_root( cache: RedisCacheStorage, is_known_private: bool, private_id: Option<&str>, + expose_keys_in_context: bool, mut request: subgraph::Request, ) -> Result, BoxError> { let body = request.subgraph_request.body_mut(); @@ -822,6 +873,36 @@ async fn cache_lookup_root( .context .extensions() .with_lock(|mut lock| lock.insert(control)); + if expose_keys_in_context { + let request_id = request.id.clone(); + let cache_control_header = value.0.control.to_cache_control_header()?; + request.context.upsert::<_, CacheKeysContext>( + CONTEXT_CACHE_KEYS, + |mut val| { + match val.get_mut(&request_id) { + Some(v) => { + v.push(CacheKeyContext { + key: key.clone(), + status: CacheKeyStatus::Cached, + cache_control: cache_control_header, + }); + } + None => { + val.insert( + request_id, + vec![CacheKeyContext { + key: key.clone(), + status: CacheKeyStatus::Cached, + cache_control: cache_control_header, + }], + ); + } + } + + val + }, + )?; + } let mut response = subgraph::Response::builder() .data(value.0.data) @@ -851,6 +932,7 @@ async fn cache_lookup_entities( is_known_private: bool, private_id: Option<&str>, mut request: subgraph::Request, + expose_keys_in_context: bool, ) -> Result, BoxError> { let body = request.subgraph_request.body_mut(); @@ -893,6 +975,46 @@ async fn cache_lookup_entities( let (new_representations, cache_result, cache_control) = filter_representations(&name, representations, keys, cache_result, &request.context)?; + if expose_keys_in_context { + let mut cache_entries = Vec::with_capacity(cache_result.len()); + for intermediate_result in &cache_result { + match &intermediate_result.cache_entry { + Some(cache_entry) => { + cache_entries.push(CacheKeyContext { + key: intermediate_result.key.clone(), + status: CacheKeyStatus::Cached, + cache_control: cache_entry.control.to_cache_control_header()?, + }); + } + None => { + cache_entries.push(CacheKeyContext { + key: intermediate_result.key.clone(), + status: CacheKeyStatus::New, + cache_control: match &cache_control { + Some(cc) => cc.to_cache_control_header()?, + None => CacheControl::default().to_cache_control_header()?, + }, + }); + } + } + } + let request_id = request.id.clone(); + request + .context + .upsert::<_, CacheKeysContext>(CONTEXT_CACHE_KEYS, |mut v| { + match v.get_mut(&request_id) { + Some(cache_keys) => { + cache_keys.append(&mut cache_entries); + } + None => { + v.insert(request_id, cache_entries); + } + } + + v + })?; + } + if !new_representations.is_empty() { body.variables .insert(REPRESENTATIONS, new_representations.into()); @@ -954,6 +1076,7 @@ async fn cache_store_root_from_response( response: &subgraph::Response, cache_control: CacheControl, cache_key: String, + expose_keys_in_context: bool, ) -> Result<(), BoxError> { if let Some(data) = response.response.body().data.as_ref() { let ttl: Option = cache_control @@ -964,6 +1087,37 @@ async fn cache_store_root_from_response( if response.response.body().errors.is_empty() && cache_control.should_store() { let span = tracing::info_span!("cache.entity.store"); let data = data.clone(); + if expose_keys_in_context { + let response_id = response.id.clone(); + let cache_control_header = cache_control.to_cache_control_header()?; + + response + .context + .upsert::<_, CacheKeysContext>(CONTEXT_CACHE_KEYS, |mut val| { + match val.get_mut(&response_id) { + Some(v) => { + v.push(CacheKeyContext { + key: cache_key.clone(), + status: CacheKeyStatus::New, + cache_control: cache_control_header, + }); + } + None => { + val.insert( + response_id, + vec![CacheKeyContext { + key: cache_key.clone(), + status: CacheKeyStatus::New, + cache_control: cache_control_header, + }], + ); + } + } + + val + })?; + } + tokio::spawn(async move { cache .insert( @@ -1419,3 +1573,42 @@ fn assemble_response_from_errors( } (new_entities, new_errors) } + +pub(crate) type CacheKeysContext = HashMap>; + +#[derive(Clone, Debug, Deserialize, Serialize)] +#[cfg_attr(test, derive(PartialEq, Eq, Hash, PartialOrd, Ord))] +pub(crate) struct CacheKeyContext { + key: String, + status: CacheKeyStatus, + cache_control: String, +} + +#[derive(Clone, Debug, Deserialize, Serialize)] +#[cfg_attr(test, derive(PartialEq, Eq, Hash))] +#[serde(rename_all = "snake_case")] +pub(crate) enum CacheKeyStatus { + /// New cache key inserted in the cache + New, + /// Key that was already in the cache + Cached, +} + +#[cfg(test)] +impl PartialOrd for CacheKeyStatus { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +#[cfg(test)] +impl Ord for CacheKeyStatus { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + match (self, other) { + (CacheKeyStatus::New, CacheKeyStatus::New) => std::cmp::Ordering::Equal, + (CacheKeyStatus::New, CacheKeyStatus::Cached) => std::cmp::Ordering::Greater, + (CacheKeyStatus::Cached, CacheKeyStatus::New) => std::cmp::Ordering::Less, + (CacheKeyStatus::Cached, CacheKeyStatus::Cached) => std::cmp::Ordering::Equal, + } + } +} diff --git a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__insert-2.snap b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__insert-2.snap index e3d6799c33..7d3bb156a2 100644 --- a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__insert-2.snap +++ b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__insert-2.snap @@ -1,17 +1,7 @@ --- source: apollo-router/src/plugins/cache/tests.rs -expression: response +expression: response.response.headers().get(CACHE_CONTROL) --- -{ - "data": { - "currentUser": { - "activeOrganization": { - "id": "1", - "creatorUser": { - "__typename": "User", - "id": 2 - } - } - } - } -} +Some( + "public", +) diff --git a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__insert-3.snap b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__insert-3.snap index 7d3bb156a2..e3d6799c33 100644 --- a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__insert-3.snap +++ b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__insert-3.snap @@ -1,7 +1,17 @@ --- source: apollo-router/src/plugins/cache/tests.rs -expression: response.response.headers().get(CACHE_CONTROL) +expression: response --- -Some( - "public", -) +{ + "data": { + "currentUser": { + "activeOrganization": { + "id": "1", + "creatorUser": { + "__typename": "User", + "id": 2 + } + } + } + } +} diff --git a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__insert-4.snap b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__insert-4.snap index e3d6799c33..7d3bb156a2 100644 --- a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__insert-4.snap +++ b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__insert-4.snap @@ -1,17 +1,7 @@ --- source: apollo-router/src/plugins/cache/tests.rs -expression: response +expression: response.response.headers().get(CACHE_CONTROL) --- -{ - "data": { - "currentUser": { - "activeOrganization": { - "id": "1", - "creatorUser": { - "__typename": "User", - "id": 2 - } - } - } - } -} +Some( + "public", +) diff --git a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__insert-5.snap b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__insert-5.snap new file mode 100644 index 0000000000..dd1ee738c2 --- /dev/null +++ b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__insert-5.snap @@ -0,0 +1,16 @@ +--- +source: apollo-router/src/plugins/cache/tests.rs +expression: cache_keys +--- +[ + { + "key": "version:1.0:subgraph:orga:type:Organization:entity:5811967f540d300d249ab30ae681359a7815fdb5d3dc71a94be1d491006a6b27:hash:d0b09a1a50750b5e95f73a196acf6ef5a8d60bf19599854b0dbee5dec6ee7ed6:data:d9d84a3c7ffc27b0190a671212f3740e5b8478e84e23825830e97822e25cf05c", + "status": "cached", + "cache_control": "public" + }, + { + "key": "version:1.0:subgraph:user:type:Query:hash:a3b7f56680be04e3ae646cf8a025aed165e8dd0f6c3dc7c95d745f8cb1348083:data:d9d84a3c7ffc27b0190a671212f3740e5b8478e84e23825830e97822e25cf05c", + "status": "cached", + "cache_control": "public" + } +] diff --git a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__insert-6.snap b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__insert-6.snap new file mode 100644 index 0000000000..e3d6799c33 --- /dev/null +++ b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__insert-6.snap @@ -0,0 +1,17 @@ +--- +source: apollo-router/src/plugins/cache/tests.rs +expression: response +--- +{ + "data": { + "currentUser": { + "activeOrganization": { + "id": "1", + "creatorUser": { + "__typename": "User", + "id": 2 + } + } + } + } +} diff --git a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__insert.snap b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__insert.snap index 7d3bb156a2..1375808b78 100644 --- a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__insert.snap +++ b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__insert.snap @@ -1,7 +1,16 @@ --- source: apollo-router/src/plugins/cache/tests.rs -expression: response.response.headers().get(CACHE_CONTROL) +expression: cache_keys --- -Some( - "public", -) +[ + { + "key": "version:1.0:subgraph:orga:type:Organization:entity:5811967f540d300d249ab30ae681359a7815fdb5d3dc71a94be1d491006a6b27:hash:d0b09a1a50750b5e95f73a196acf6ef5a8d60bf19599854b0dbee5dec6ee7ed6:data:d9d84a3c7ffc27b0190a671212f3740e5b8478e84e23825830e97822e25cf05c", + "status": "new", + "cache_control": "public" + }, + { + "key": "version:1.0:subgraph:user:type:Query:hash:a3b7f56680be04e3ae646cf8a025aed165e8dd0f6c3dc7c95d745f8cb1348083:data:d9d84a3c7ffc27b0190a671212f3740e5b8478e84e23825830e97822e25cf05c", + "status": "new", + "cache_control": "public" + } +] diff --git a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__no_data-2.snap b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__no_data-2.snap index 6e58a2d437..b9832aaeaa 100644 --- a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__no_data-2.snap +++ b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__no_data-2.snap @@ -10,30 +10,11 @@ expression: response "id": "1", "name": "Organization 1" }, - { - "id": "2", - "name": null - }, { "id": "3", "name": "Organization 3" } ] } - }, - "errors": [ - { - "message": "HTTP fetch failed from 'orga': orga not found", - "path": [ - "currentUser", - "allOrganizations", - 1 - ], - "extensions": { - "code": "SUBREQUEST_HTTP_ERROR", - "service": "orga", - "reason": "orga not found" - } - } - ] + } } diff --git a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__no_data-3.snap b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__no_data-3.snap new file mode 100644 index 0000000000..1322b59275 --- /dev/null +++ b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__no_data-3.snap @@ -0,0 +1,16 @@ +--- +source: apollo-router/src/plugins/cache/tests.rs +expression: cache_keys +--- +[ + { + "key": "version:1.0:subgraph:orga:type:Organization:entity:5221ff42b311b757445c096c023cee4fefab5de49735e421c494f1119326317b:hash:cffb47a84aff0aea6a447e33caf3b275bdc7f71689d75f56647242b3b9f5e13b:data:d9d84a3c7ffc27b0190a671212f3740e5b8478e84e23825830e97822e25cf05c", + "status": "cached", + "cache_control": "[REDACTED]" + }, + { + "key": "version:1.0:subgraph:orga:type:Organization:entity:5811967f540d300d249ab30ae681359a7815fdb5d3dc71a94be1d491006a6b27:hash:cffb47a84aff0aea6a447e33caf3b275bdc7f71689d75f56647242b3b9f5e13b:data:d9d84a3c7ffc27b0190a671212f3740e5b8478e84e23825830e97822e25cf05c", + "status": "cached", + "cache_control": "[REDACTED]" + } +] diff --git a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__no_data-4.snap b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__no_data-4.snap new file mode 100644 index 0000000000..6e58a2d437 --- /dev/null +++ b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__no_data-4.snap @@ -0,0 +1,39 @@ +--- +source: apollo-router/src/plugins/cache/tests.rs +expression: response +--- +{ + "data": { + "currentUser": { + "allOrganizations": [ + { + "id": "1", + "name": "Organization 1" + }, + { + "id": "2", + "name": null + }, + { + "id": "3", + "name": "Organization 3" + } + ] + } + }, + "errors": [ + { + "message": "HTTP fetch failed from 'orga': orga not found", + "path": [ + "currentUser", + "allOrganizations", + 1 + ], + "extensions": { + "code": "SUBREQUEST_HTTP_ERROR", + "service": "orga", + "reason": "orga not found" + } + } + ] +} diff --git a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__no_data.snap b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__no_data.snap index b9832aaeaa..87c750131f 100644 --- a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__no_data.snap +++ b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__no_data.snap @@ -1,20 +1,16 @@ --- source: apollo-router/src/plugins/cache/tests.rs -expression: response +expression: cache_keys --- -{ - "data": { - "currentUser": { - "allOrganizations": [ - { - "id": "1", - "name": "Organization 1" - }, - { - "id": "3", - "name": "Organization 3" - } - ] - } +[ + { + "key": "version:1.0:subgraph:orga:type:Organization:entity:5221ff42b311b757445c096c023cee4fefab5de49735e421c494f1119326317b:hash:cffb47a84aff0aea6a447e33caf3b275bdc7f71689d75f56647242b3b9f5e13b:data:d9d84a3c7ffc27b0190a671212f3740e5b8478e84e23825830e97822e25cf05c", + "status": "new", + "cache_control": "[REDACTED]" + }, + { + "key": "version:1.0:subgraph:orga:type:Organization:entity:5811967f540d300d249ab30ae681359a7815fdb5d3dc71a94be1d491006a6b27:hash:cffb47a84aff0aea6a447e33caf3b275bdc7f71689d75f56647242b3b9f5e13b:data:d9d84a3c7ffc27b0190a671212f3740e5b8478e84e23825830e97822e25cf05c", + "status": "new", + "cache_control": "[REDACTED]" } -} +] diff --git a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__private-3.snap b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__private-3.snap index 3c363a2b4d..c9839a8823 100644 --- a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__private-3.snap +++ b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__private-3.snap @@ -1,9 +1,16 @@ --- source: apollo-router/src/plugins/cache/tests.rs -expression: response +expression: cache_keys --- -{ - "data": { - "currentUser": null +[ + { + "key": "version:1.0:subgraph:orga:type:Organization:entity:5811967f540d300d249ab30ae681359a7815fdb5d3dc71a94be1d491006a6b27:hash:d0b09a1a50750b5e95f73a196acf6ef5a8d60bf19599854b0dbee5dec6ee7ed6:data:d9d84a3c7ffc27b0190a671212f3740e5b8478e84e23825830e97822e25cf05c:03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", + "status": "cached", + "cache_control": "private" + }, + { + "key": "version:1.0:subgraph:user:type:Query:hash:a3b7f56680be04e3ae646cf8a025aed165e8dd0f6c3dc7c95d745f8cb1348083:data:d9d84a3c7ffc27b0190a671212f3740e5b8478e84e23825830e97822e25cf05c:03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", + "status": "cached", + "cache_control": "private" } -} +] diff --git a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__private-4.snap b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__private-4.snap new file mode 100644 index 0000000000..e3d6799c33 --- /dev/null +++ b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__private-4.snap @@ -0,0 +1,17 @@ +--- +source: apollo-router/src/plugins/cache/tests.rs +expression: response +--- +{ + "data": { + "currentUser": { + "activeOrganization": { + "id": "1", + "creatorUser": { + "__typename": "User", + "id": 2 + } + } + } + } +} diff --git a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__private-5.snap b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__private-5.snap new file mode 100644 index 0000000000..c9839a8823 --- /dev/null +++ b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__private-5.snap @@ -0,0 +1,16 @@ +--- +source: apollo-router/src/plugins/cache/tests.rs +expression: cache_keys +--- +[ + { + "key": "version:1.0:subgraph:orga:type:Organization:entity:5811967f540d300d249ab30ae681359a7815fdb5d3dc71a94be1d491006a6b27:hash:d0b09a1a50750b5e95f73a196acf6ef5a8d60bf19599854b0dbee5dec6ee7ed6:data:d9d84a3c7ffc27b0190a671212f3740e5b8478e84e23825830e97822e25cf05c:03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", + "status": "cached", + "cache_control": "private" + }, + { + "key": "version:1.0:subgraph:user:type:Query:hash:a3b7f56680be04e3ae646cf8a025aed165e8dd0f6c3dc7c95d745f8cb1348083:data:d9d84a3c7ffc27b0190a671212f3740e5b8478e84e23825830e97822e25cf05c:03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", + "status": "cached", + "cache_control": "private" + } +] diff --git a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__private-6.snap b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__private-6.snap new file mode 100644 index 0000000000..3c363a2b4d --- /dev/null +++ b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__private-6.snap @@ -0,0 +1,9 @@ +--- +source: apollo-router/src/plugins/cache/tests.rs +expression: response +--- +{ + "data": { + "currentUser": null + } +} diff --git a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__private.snap b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__private.snap index e3d6799c33..69027e4644 100644 --- a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__private.snap +++ b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__private.snap @@ -1,17 +1,16 @@ --- source: apollo-router/src/plugins/cache/tests.rs -expression: response +expression: cache_keys --- -{ - "data": { - "currentUser": { - "activeOrganization": { - "id": "1", - "creatorUser": { - "__typename": "User", - "id": 2 - } - } - } +[ + { + "key": "version:1.0:subgraph:orga:type:Organization:entity:5811967f540d300d249ab30ae681359a7815fdb5d3dc71a94be1d491006a6b27:hash:d0b09a1a50750b5e95f73a196acf6ef5a8d60bf19599854b0dbee5dec6ee7ed6:data:d9d84a3c7ffc27b0190a671212f3740e5b8478e84e23825830e97822e25cf05c", + "status": "new", + "cache_control": "private" + }, + { + "key": "version:1.0:subgraph:user:type:Query:hash:a3b7f56680be04e3ae646cf8a025aed165e8dd0f6c3dc7c95d745f8cb1348083:data:d9d84a3c7ffc27b0190a671212f3740e5b8478e84e23825830e97822e25cf05c:03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4", + "status": "new", + "cache_control": "private" } -} +] diff --git a/apollo-router/src/plugins/cache/tests.rs b/apollo-router/src/plugins/cache/tests.rs index 24dc71d3ab..3633a21bcc 100644 --- a/apollo-router/src/plugins/cache/tests.rs +++ b/apollo-router/src/plugins/cache/tests.rs @@ -16,7 +16,10 @@ use super::entity::EntityCache; use crate::cache::redis::RedisCacheStorage; use crate::plugin::test::MockSubgraph; use crate::plugin::test::MockSubgraphService; +use crate::plugins::cache::entity::CacheKeyContext; +use crate::plugins::cache::entity::CacheKeysContext; use crate::plugins::cache::entity::Subgraph; +use crate::plugins::cache::entity::CONTEXT_CACHE_KEYS; use crate::services::subgraph; use crate::services::supergraph; use crate::Context; @@ -227,6 +230,10 @@ async fn insert() { .build() .unwrap(); let mut response = service.oneshot(request).await.unwrap(); + let cache_keys: CacheKeysContext = response.context.get(CONTEXT_CACHE_KEYS).unwrap().unwrap(); + let mut cache_keys: Vec = cache_keys.into_values().flatten().collect(); + cache_keys.sort(); + insta::assert_json_snapshot!(cache_keys); insta::assert_debug_snapshot!(response.response.headers().get(CACHE_CONTROL)); let response = response.next_response().await.unwrap(); @@ -255,6 +262,11 @@ async fn insert() { let mut response = service.oneshot(request).await.unwrap(); insta::assert_debug_snapshot!(response.response.headers().get(CACHE_CONTROL)); + let cache_keys: CacheKeysContext = response.context.get(CONTEXT_CACHE_KEYS).unwrap().unwrap(); + let mut cache_keys: Vec = cache_keys.into_values().flatten().collect(); + cache_keys.sort(); + insta::assert_json_snapshot!(cache_keys); + let response = response.next_response().await.unwrap(); insta::assert_json_snapshot!(response); @@ -434,14 +446,13 @@ async fn private() { .context(context) .build() .unwrap(); - let response = service - .oneshot(request) - .await - .unwrap() - .next_response() - .await - .unwrap(); + let mut response = service.clone().oneshot(request).await.unwrap(); + let cache_keys: CacheKeysContext = response.context.get(CONTEXT_CACHE_KEYS).unwrap().unwrap(); + let mut cache_keys: Vec = cache_keys.into_values().flatten().collect(); + cache_keys.sort(); + insta::assert_json_snapshot!(cache_keys); + let response = response.next_response().await.unwrap(); insta::assert_json_snapshot!(response); println!("\nNOW WITHOUT SUBGRAPHS\n"); @@ -463,14 +474,13 @@ async fn private() { .context(context) .build() .unwrap(); - let response = service - .clone() - .oneshot(request) - .await - .unwrap() - .next_response() - .await - .unwrap(); + let mut response = service.clone().oneshot(request).await.unwrap(); + let cache_keys: CacheKeysContext = response.context.get(CONTEXT_CACHE_KEYS).unwrap().unwrap(); + let mut cache_keys: Vec = cache_keys.into_values().flatten().collect(); + cache_keys.sort(); + insta::assert_json_snapshot!(cache_keys); + + let response = response.next_response().await.unwrap(); insta::assert_json_snapshot!(response); @@ -483,15 +493,16 @@ async fn private() { .context(context) .build() .unwrap(); - let response = service - .clone() - .oneshot(request) - .await - .unwrap() - .next_response() - .await - .unwrap(); + let mut response = service.clone().oneshot(request).await.unwrap(); + assert!(response + .context + .get::<_, CacheKeysContext>(CONTEXT_CACHE_KEYS) + .ok() + .flatten() + .is_none()); + insta::assert_json_snapshot!(cache_keys); + let response = response.next_response().await.unwrap(); insta::assert_json_snapshot!(response); } @@ -589,6 +600,18 @@ async fn no_data() { .unwrap(); let mut response = service.oneshot(request).await.unwrap(); + let cache_keys: CacheKeysContext = response.context.get(CONTEXT_CACHE_KEYS).unwrap().unwrap(); + let mut cache_keys: Vec = cache_keys.into_values().flatten().collect(); + cache_keys.sort(); + insta::assert_json_snapshot!(cache_keys, { + "[].cache_control" => insta::dynamic_redaction(|value, _path| { + let cache_control = value.as_str().unwrap().to_string(); + assert!(cache_control.contains("max-age=")); + assert!(cache_control.contains("public")); + "[REDACTED]" + }) + }); + let response = response.next_response().await.unwrap(); insta::assert_json_snapshot!(response); @@ -652,6 +675,18 @@ async fn no_data() { .build() .unwrap(); let mut response = service.oneshot(request).await.unwrap(); + + let cache_keys: CacheKeysContext = response.context.get(CONTEXT_CACHE_KEYS).unwrap().unwrap(); + let mut cache_keys: Vec = cache_keys.into_values().flatten().collect(); + cache_keys.sort(); + insta::assert_json_snapshot!(cache_keys, { + "[].cache_control" => insta::dynamic_redaction(|value, _path| { + let cache_control = value.as_str().unwrap().to_string(); + assert!(cache_control.contains("max-age=")); + assert!(cache_control.contains("public")); + "[REDACTED]" + }) + }); let response = response.next_response().await.unwrap(); insta::assert_json_snapshot!(response); diff --git a/docs/source/routing/performance/caching/entity.mdx b/docs/source/routing/performance/caching/entity.mdx index 76e9a616b1..64618ca2d5 100644 --- a/docs/source/routing/performance/caching/entity.mdx +++ b/docs/source/routing/performance/caching/entity.mdx @@ -162,6 +162,7 @@ For example: # Enable entity caching globally preview_entity_cache: enabled: true + expose_keys_in_context: true # Optional, it will expose cache keys in the context in order to use it in coprocessors or Rhai subgraph: all: enabled: true diff --git a/examples/coprocessor-surrogate-cache-key/README.md b/examples/coprocessor-surrogate-cache-key/README.md new file mode 100644 index 0000000000..059c6466f5 --- /dev/null +++ b/examples/coprocessor-surrogate-cache-key/README.md @@ -0,0 +1,124 @@ +## Context + +Existing caching systems often support a concept of surrogate keys, where a key can be linked to a specific piece of cached data, independently of the actual cache key. + +As an example, a news website might want to invalidate all cached articles linked to a specific company or person following an event. To that end, when returning the article, the service can add a surrogate key to the article response, and the cache would keep a map from surrogate keys to cache keys. + +## Surrogate keys and the routerโ€™s entity cache + +To support a surrogate key system with the entity caching in the router, we make the following assumptions: + +- The subgraph returns surrogate keys with the response. The router will not manipulate those surrogate keys directly. Instead, it leaves that task to a coprocessor +- The coprocessor tasked with managing surrogate keys will store the mapping from surrogate keys to cache keys. It will be useful to invalidate all cache keys related to a surrogate cache key in Redis. +- The router will expose a way to gather the cache keys used in a subgraph request + +### Router side support + +The router has two features to support surrogate cache key: + +- An id field for subgraph requests and responses. This is a random, unique id per subgraph call that can be used to keep state between the request and response side, and keep data from the various subgraph calls separately for the entire client request. You have to enable it in configuration (`subgraph_request_id`): + +```yaml title=router.yaml +coprocessor: + url: http://127.0.0.1:3000 # mandatory URL which is the address of the coprocessor + supergraph: + response: + context: true + subgraph: + all: + response: + subgraph_request_id: true + context: true +``` + +- The entity cache has an option to store in the request context, at the key `apollo::entity_cache::cached_keys_status`, a map `subgraph request id => cache keys` only when it's enabled in the configuration (`expose_keys_in_context`)): + +```yaml title=router.yaml +preview_entity_cache: + enabled: true + expose_keys_in_context: true + metrics: + enabled: true + invalidation: + listen: 0.0.0.0:4000 + path: /invalidation + # Configure entity caching per subgraph + subgraph: + all: + enabled: true + # Configure Redis + redis: + urls: ["redis://localhost:6379"] + ttl: 24h # Optional, by default no expiration +``` + +The coprocessor will then work at two stages: + +- Subgraph response: + - Extract the subgraph request id + - Extract the list of surrogate keys from the response +- Supergraph stage: + - Extract the map `subgraph request id => cache keys` + - Match it with the surrogate cache keys obtained at the subgraph response stage + +The coprocessor then has a map of `surrogate keys => cache keys` that it can use to invalidate cached data directly from Redis. + +### Example workflow + +- The router receives a client request +- The router starts a subgraph request: + - The entity cache plugin checks if the request has a corresponding cached entry: + - If the entire response can be obtained from cache, we return a response here + - If it cannot be obtained, or only partially (\_entities query), a request is transmitted to the subgraph + - The subgraph responds to the request. The response can contain a list of surrogate keys in a header: `Surrogate-Keys: homepage, feed` + - The subgraph response stage coprocessor extracts the surrogate keys from headers, and stores it in the request context, associated with the subgraph request id `0e67db40-e98d-4ad7-bb60-2012fb5db504`: + +```json +{ + "โ€‹0ee3bf47-5e8d-47e3-8e7e-b05ae877d9c7": ["homepage", "feed"] +} +``` + +- The entity cache processes the subgraph response: + - It generates a new subgraph response by interspersing data it got from cache with data from the original response + - It stores the list of keys in the context. `new` indicates newly cached data coming from the subgraph, linked to the surrogate keys, while `cached` is data obtained from the cache. These are the keys directly used in Redis: + +```json +{ + "apollo::entity_cache::cached_keys_status": { + "0ee3bf47-5e8d-47e3-8e7e-b05ae877d9c7": [ + { + "key": "version:1.0:subgraph:products:type:Query:hash:af9febfacdc8244afc233a857e3c4b85a749355707763dc523a6d9e8964e9c8d:data:d9d84a3c7ffc27b0190a671212f3740e5b8478e84e23825830e97822e25cf05c", + "status": "new", + "cache_control": "max-age=60,public" + } + ] + } +} +``` + +- The supergraph response stage loads data from the context and creates the mapping: + +```json +{ + "homepage": [ + { + "key": "version:1.0:subgraph:products:type:Query:hash:af9febfacdc8244afc233a857e3c4b85a749355707763dc523a6d9e8964e9c8d:data:d9d84a3c7ffc27b0190a671212f3740e5b8478e84e23825830e97822e25cf05c", + "status": "new", + "cache_control": "max-age=60,public" + } + ], + "feed": [ + { + "key": "version:1.0:subgraph:products:type:Query:hash:af9febfacdc8244afc233a857e3c4b85a749355707763dc523a6d9e8964e9c8d:data:d9d84a3c7ffc27b0190a671212f3740e5b8478e84e23825830e97822e25cf05c", + "status": "new", + "cache_control": "max-age=60,public" + } + ] +} +``` + +- When a surrogate key must be used to invalidate data, that mapping is used to obtained the related cache keys + + +In this example we provide a very simple implementation using in memory data in NodeJs. It just prints the mapping at the supergraph response level to show you how you can create that mapping. diff --git a/examples/coprocessor-surrogate-cache-key/nodejs/.gitignore b/examples/coprocessor-surrogate-cache-key/nodejs/.gitignore new file mode 100644 index 0000000000..d5f19d89b3 --- /dev/null +++ b/examples/coprocessor-surrogate-cache-key/nodejs/.gitignore @@ -0,0 +1,2 @@ +node_modules +package-lock.json diff --git a/examples/coprocessor-surrogate-cache-key/nodejs/README.md b/examples/coprocessor-surrogate-cache-key/nodejs/README.md new file mode 100644 index 0000000000..e65978e36b --- /dev/null +++ b/examples/coprocessor-surrogate-cache-key/nodejs/README.md @@ -0,0 +1,16 @@ +# External Subgraph nodejs example + +This is an example that involves a nodejs coprocessor alongside a router. + +## Usage + +- Start the coprocessor: + +```bash +$ npm ci && npm run start +``` + +- Start the router +``` +$ APOLLO_KEY="YOUR_APOLLO_KEY" APOLLO_GRAPH_REF="YOUR_APOLLO_GRAPH_REF" cargo run -- --configuration router.yaml +``` diff --git a/examples/coprocessor-surrogate-cache-key/nodejs/package.json b/examples/coprocessor-surrogate-cache-key/nodejs/package.json new file mode 100644 index 0000000000..1c3ef66300 --- /dev/null +++ b/examples/coprocessor-surrogate-cache-key/nodejs/package.json @@ -0,0 +1,15 @@ +{ + "name": "coprocessor", + "version": "1.0.0", + "description": "A coprocessor example for the router", + "main": "src/index.js", + "scripts": { + "start": "node src/index.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "express": "^4.18.2" + } +} \ No newline at end of file diff --git a/examples/coprocessor-surrogate-cache-key/nodejs/router.yaml b/examples/coprocessor-surrogate-cache-key/nodejs/router.yaml new file mode 100644 index 0000000000..d3b36e3966 --- /dev/null +++ b/examples/coprocessor-surrogate-cache-key/nodejs/router.yaml @@ -0,0 +1,36 @@ +supergraph: + listen: 127.0.0.1:4000 + introspection: true +sandbox: + enabled: true +homepage: + enabled: false +include_subgraph_errors: + all: true # Propagate errors from all subraphs + +coprocessor: + url: http://127.0.0.1:3000 # mandatory URL which is the address of the coprocessor + supergraph: + response: + context: true + subgraph: + all: + response: + subgraph_request_id: true + context: true +preview_entity_cache: + enabled: true + expose_keys_in_context: true + metrics: + enabled: true + invalidation: + listen: 0.0.0.0:4000 + path: /invalidation + # Configure entity caching per subgraph + subgraph: + all: + enabled: true + # Configure Redis + redis: + urls: ["redis://localhost:6379"] + ttl: 24h # Optional, by default no expiration \ No newline at end of file diff --git a/examples/coprocessor-surrogate-cache-key/nodejs/src/index.js b/examples/coprocessor-surrogate-cache-key/nodejs/src/index.js new file mode 100644 index 0000000000..daadb50740 --- /dev/null +++ b/examples/coprocessor-surrogate-cache-key/nodejs/src/index.js @@ -0,0 +1,110 @@ +const express = require("express"); +const app = express(); +const port = 3000; + +app.use(express.json()); + +// This is for demo purpose and will keep growing over the time +// It saves the value of surrogate cache keys returned by a subgraph request +let surrogateKeys = new Map(); +// Example: +// { +// "โ€‹โ€‹0e67db40-e98d-4ad7-bb60-2012fb5db504": [ +// "elections", +// "sp500" +// ], +// "โ€‹โ€‹0d77db40-e98d-4ad7-bb60-2012fb5db555": [ +// "homepage" +// ] +// } +// -------------- +// For every surrogate cache key we know the related cache keys +// Example: +// { +// "elections": [ +// "version:1.0:subgraph:reviews:type:Product:entity:4e48855987eae27208b466b941ecda5fb9b88abc03301afef6e4099a981889e9:hash:1de543dab57fde0f00247922ccc4f76d4c916ae26a89dd83cd1a62300d0cda20:data:d9d84a3c7ffc27b0190a671212f3740e5b8478e84e23825830e97822e25cf05c" +// ], +// "sp500": [ +// "version:1.0:subgraph:reviews:type:Product:entity:4e48855987eae27208b466b941ecda5fb9b88abc03301afef6e4099a981889e9:hash:1de543dab57fde0f00247922ccc4f76d4c916ae26a89dd83cd1a62300d0cda20:data:d9d84a3c7ffc27b0190a671212f3740e5b8478e84e23825830e97822e25cf05c" +// ] +// } + +app.post("/", (req, res) => { + const request = req.body; + console.log("โœ‰๏ธ Got payload:"); + console.log(JSON.stringify(request, null, 2)); + switch (request.stage) { + case "SubgraphResponse": + request.headers["surrogate-keys"] = ["homepage, feed"]; // To simulate + // Fetch the surrogate keys returned by the subgraph to create a mapping between subgraph request id and surrogate keys, to create the final mapping later + // Example: + // { + // "โ€‹โ€‹0e67db40-e98d-4ad7-bb60-2012fb5db504": [ + // "elections", + // "sp500" + // ] + // } + if (request.headers["surrogate-keys"] && request.subgraphRequestId) { + let keys = request.headers["surrogate-keys"] + .join(",") + .split(",") + .map((k) => k.trim()); + + surrogateKeys.set(request.subgraphRequestId, keys); + console.log("surrogateKeys", surrogateKeys); + } + break; + case "SupergraphResponse": + if ( + request.context && + request.context.entries && + request.context.entries["apollo::entity_cache::cached_keys_status"] + ) { + let contextEntry = + request.context.entries["apollo::entity_cache::cached_keys_status"]; + let mapping = {}; + Object.keys(contextEntry).forEach((request_id) => { + let cache_keys = contextEntry[`${request_id}`]; + let surrogateCachekeys = surrogateKeys.get(request_id); + if (surrogateCachekeys) { + // Create the mapping between surrogate cache keys and effective cache keys + // Example: + // { + // "elections": [ + // "version:1.0:subgraph:reviews:type:Product:entity:4e48855987eae27208b466b941ecda5fb9b88abc03301afef6e4099a981889e9:hash:1de543dab57fde0f00247922ccc4f76d4c916ae26a89dd83cd1a62300d0cda20:data:d9d84a3c7ffc27b0190a671212f3740e5b8478e84e23825830e97822e25cf05c" + // ], + // "sp500": [ + // "version:1.0:subgraph:reviews:type:Product:entity:4e48855987eae27208b466b941ecda5fb9b88abc03301afef6e4099a981889e9:hash:1de543dab57fde0f00247922ccc4f76d4c916ae26a89dd83cd1a62300d0cda20:data:d9d84a3c7ffc27b0190a671212f3740e5b8478e84e23825830e97822e25cf05c" + // ] + // } + + surrogateCachekeys.reduce((acc, current) => { + if (acc[`${current}`]) { + acc[`${current}`] = acc[`${current}`].concat(cache_keys); + } else { + acc[`${current}`] = cache_keys; + } + + return acc; + }, mapping); + } + }); + + console.log(mapping); + } + break; + default: + return res.json(request); + } + res.json(request); +}); + +app.listen(port, () => { + console.log(`๐Ÿš€ Coprocessor running on port ${port}`); + console.log( + `Run a router with the provided router.yaml configuration to test the example:` + ); + console.log( + `APOLLO_KEY="YOUR_APOLLO_KEY" APOLLO_GRAPH_REF="YOUR_APOLLO_GRAPH_REF" cargo run -- --configuration router.yaml` + ); +}); From e79333ae392581d4140ecd3a770dd8342c02367f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e?= Date: Wed, 20 Nov 2024 12:05:49 +0000 Subject: [PATCH 50/77] fix(federation): remove special-casing of adding reserved or built-in items to a schema (#6270) --- apollo-federation/src/schema/position.rs | 291 ++++------------------- apollo-federation/src/supergraph/mod.rs | 1 + 2 files changed, 42 insertions(+), 250 deletions(-) diff --git a/apollo-federation/src/schema/position.rs b/apollo-federation/src/schema/position.rs index 99701a5db1..5de2402f8c 100644 --- a/apollo-federation/src/schema/position.rs +++ b/apollo-federation/src/schema/position.rs @@ -4,7 +4,6 @@ use std::fmt::Formatter; use std::ops::Deref; use apollo_compiler::ast; -use apollo_compiler::collections::IndexSet; use apollo_compiler::name; use apollo_compiler::schema::Component; use apollo_compiler::schema::ComponentName; @@ -25,10 +24,10 @@ use apollo_compiler::Name; use apollo_compiler::Node; use apollo_compiler::Schema; use either::Either; -use lazy_static::lazy_static; use serde::Serialize; use strum::IntoEnumIterator; +use crate::bail; use crate::error::FederationError; use crate::error::SingleFederationError; use crate::link::database::links_metadata; @@ -1050,16 +1049,7 @@ impl ScalarTypeDefinitionPosition { pub(crate) fn pre_insert(&self, schema: &mut FederationSchema) -> Result<(), FederationError> { if schema.referencers.contains_type_name(&self.type_name) { - // TODO: Allow built-in shadowing instead of ignoring them - if is_graphql_reserved_name(&self.type_name) - || GRAPHQL_BUILTIN_SCALAR_NAMES.contains(&self.type_name) - { - return Ok(()); - } - return Err(SingleFederationError::Internal { - message: format!("Type \"{}\" has already been pre-inserted", self), - } - .into()); + bail!(r#"Type "{self}" has already been pre-inserted"#); } schema .referencers @@ -1087,22 +1077,10 @@ impl ScalarTypeDefinitionPosition { .scalar_types .contains_key(&self.type_name) { - return Err(SingleFederationError::Internal { - message: format!("Type \"{}\" has not been pre-inserted", self), - } - .into()); + bail!(r#"Type "{self}" has not been pre-inserted"#); } if schema.schema.types.contains_key(&self.type_name) { - // TODO: Allow built-in shadowing instead of ignoring them - if is_graphql_reserved_name(&self.type_name) - || GRAPHQL_BUILTIN_SCALAR_NAMES.contains(&self.type_name) - { - return Ok(()); - } - return Err(SingleFederationError::Internal { - message: format!("Type \"{}\" already exists in schema", self), - } - .into()); + bail!(r#"Type "{self}" already exists in schema"#); } schema .schema @@ -1354,14 +1332,7 @@ impl ObjectTypeDefinitionPosition { pub(crate) fn pre_insert(&self, schema: &mut FederationSchema) -> Result<(), FederationError> { if schema.referencers.contains_type_name(&self.type_name) { - // TODO: Allow built-in shadowing instead of ignoring them - if is_graphql_reserved_name(&self.type_name) { - return Ok(()); - } - return Err(SingleFederationError::Internal { - message: format!("Type \"{}\" has already been pre-inserted", self), - } - .into()); + bail!(r#"Type "{self}" has already been pre-inserted"#); } schema .referencers @@ -1389,20 +1360,10 @@ impl ObjectTypeDefinitionPosition { .object_types .contains_key(&self.type_name) { - return Err(SingleFederationError::Internal { - message: format!("Type \"{}\" has not been pre-inserted", self), - } - .into()); + bail!(r#"Type "{self}" has not been pre-inserted"#); } if schema.schema.types.contains_key(&self.type_name) { - // TODO: Allow built-in shadowing instead of ignoring them - if is_graphql_reserved_name(&self.type_name) { - return Ok(()); - } - return Err(SingleFederationError::Internal { - message: format!("Type \"{}\" already exists in schema", self), - } - .into()); + bail!(r#"Type "{self}" already exists in schema"#); } schema .schema @@ -1824,10 +1785,7 @@ impl ObjectFieldDefinitionPosition { .into()); } if self.try_get(&schema.schema).is_some() { - return Err(SingleFederationError::Internal { - message: format!("Object field \"{}\" already exists in schema", self), - } - .into()); + bail!(r#"Object field "{self}" already exists in schema"#); } self.parent() .make_mut(&mut schema.schema)? @@ -1936,10 +1894,7 @@ impl ObjectFieldDefinitionPosition { allow_built_ins: bool, ) -> Result<(), FederationError> { if !allow_built_ins && is_graphql_reserved_name(&self.field_name) { - return Err(SingleFederationError::Internal { - message: format!("Cannot insert reserved object field \"{}\"", self), - } - .into()); + bail!(r#"Cannot insert reserved object field "{self}""#); } validate_node_directives(field.directives.deref())?; for directive_reference in field.directives.iter() { @@ -1961,10 +1916,7 @@ impl ObjectFieldDefinitionPosition { allow_built_ins: bool, ) -> Result<(), FederationError> { if !allow_built_ins && is_graphql_reserved_name(&self.field_name) { - return Err(SingleFederationError::Internal { - message: format!("Cannot remove reserved object field \"{}\"", self), - } - .into()); + bail!(r#"Cannot remove reserved object field "{self}""#); } for directive_reference in field.directives.iter() { self.remove_directive_name_references(referencers, &directive_reference.name); @@ -2190,10 +2142,7 @@ impl ObjectFieldArgumentDefinitionPosition { referencers: &mut Referencers, ) -> Result<(), FederationError> { if is_graphql_reserved_name(&self.argument_name) { - return Err(SingleFederationError::Internal { - message: format!("Cannot insert reserved object field argument \"{}\"", self), - } - .into()); + bail!(r#"Cannot insert reserved object field argument "{self}""#); } validate_node_directives(argument.directives.deref())?; for directive_reference in argument.directives.iter() { @@ -2208,10 +2157,7 @@ impl ObjectFieldArgumentDefinitionPosition { referencers: &mut Referencers, ) -> Result<(), FederationError> { if is_graphql_reserved_name(&self.argument_name) { - return Err(SingleFederationError::Internal { - message: format!("Cannot remove reserved object field argument \"{}\"", self), - } - .into()); + bail!(r#"Cannot remove reserved object field argument "{self}""#); } for directive_reference in argument.directives.iter() { self.remove_directive_name_references(referencers, &directive_reference.name); @@ -2423,14 +2369,7 @@ impl InterfaceTypeDefinitionPosition { pub(crate) fn pre_insert(&self, schema: &mut FederationSchema) -> Result<(), FederationError> { if schema.referencers.contains_type_name(&self.type_name) { - // TODO: Allow built-in shadowing instead of ignoring them - if is_graphql_reserved_name(&self.type_name) { - return Ok(()); - } - return Err(SingleFederationError::Internal { - message: format!("Type \"{}\" has already been pre-inserted", self), - } - .into()); + bail!(r#"Type "{self}" has already been pre-inserted"#); } schema .referencers @@ -2458,20 +2397,10 @@ impl InterfaceTypeDefinitionPosition { .interface_types .contains_key(&self.type_name) { - return Err(SingleFederationError::Internal { - message: format!("Type \"{}\" has not been pre-inserted", self), - } - .into()); + bail!(r#"Type "{self}" has not been pre-inserted"#); } if schema.schema.types.contains_key(&self.type_name) { - // TODO: Allow built-in shadowing instead of ignoring them - if is_graphql_reserved_name(&self.type_name) { - return Ok(()); - } - return Err(SingleFederationError::Internal { - message: format!("Type \"{}\" already exists in schema", self), - } - .into()); + bail!(r#"Type "{self}" already exists in schema"#); } schema .schema @@ -2823,10 +2752,7 @@ impl InterfaceFieldDefinitionPosition { .into()); } if self.try_get(&schema.schema).is_some() { - return Err(SingleFederationError::Internal { - message: format!("Interface field \"{}\" already exists in schema", self), - } - .into()); + bail!(r#"Interface field "{self}" already exists in schema"#); } self.parent() .make_mut(&mut schema.schema)? @@ -2935,10 +2861,7 @@ impl InterfaceFieldDefinitionPosition { allow_built_ins: bool, ) -> Result<(), FederationError> { if !allow_built_ins && is_graphql_reserved_name(&self.field_name) { - return Err(SingleFederationError::Internal { - message: format!("Cannot insert reserved interface field \"{}\"", self), - } - .into()); + bail!(r#"Cannot insert reserved interface field "{self}""#); } validate_node_directives(field.directives.deref())?; for directive_reference in field.directives.iter() { @@ -2960,10 +2883,7 @@ impl InterfaceFieldDefinitionPosition { allow_built_ins: bool, ) -> Result<(), FederationError> { if !allow_built_ins && is_graphql_reserved_name(&self.field_name) { - return Err(SingleFederationError::Internal { - message: format!("Cannot remove reserved interface field \"{}\"", self), - } - .into()); + bail!(r#"Cannot remove reserved interface field "{self}""#); } for directive_reference in field.directives.iter() { self.remove_directive_name_references(referencers, &directive_reference.name); @@ -3188,13 +3108,7 @@ impl InterfaceFieldArgumentDefinitionPosition { referencers: &mut Referencers, ) -> Result<(), FederationError> { if is_graphql_reserved_name(&self.argument_name) { - return Err(SingleFederationError::Internal { - message: format!( - "Cannot insert reserved interface field argument \"{}\"", - self - ), - } - .into()); + bail!(r#"Cannot insert reserved interface field argument "{self}""#); } validate_node_directives(argument.directives.deref())?; for directive_reference in argument.directives.iter() { @@ -3209,13 +3123,7 @@ impl InterfaceFieldArgumentDefinitionPosition { referencers: &mut Referencers, ) -> Result<(), FederationError> { if is_graphql_reserved_name(&self.argument_name) { - return Err(SingleFederationError::Internal { - message: format!( - "Cannot remove reserved interface field argument \"{}\"", - self - ), - } - .into()); + bail!(r#"Cannot remove reserved interface field argument "{self}""#); } for directive_reference in argument.directives.iter() { self.remove_directive_name_references(referencers, &directive_reference.name); @@ -3401,14 +3309,7 @@ impl UnionTypeDefinitionPosition { pub(crate) fn pre_insert(&self, schema: &mut FederationSchema) -> Result<(), FederationError> { if schema.referencers.contains_type_name(&self.type_name) { - // TODO: Allow built-in shadowing instead of ignoring them - if is_graphql_reserved_name(&self.type_name) { - return Ok(()); - } - return Err(SingleFederationError::Internal { - message: format!("Type \"{}\" has already been pre-inserted", self), - } - .into()); + bail!(r#"Type "{self}" has already been pre-inserted"#); } schema .referencers @@ -3432,20 +3333,10 @@ impl UnionTypeDefinitionPosition { .into()); } if !schema.referencers.union_types.contains_key(&self.type_name) { - return Err(SingleFederationError::Internal { - message: format!("Type \"{}\" has not been pre-inserted", self), - } - .into()); + bail!(r#"Type "{self}" has not been pre-inserted"#); } if schema.schema.types.contains_key(&self.type_name) { - // TODO: Allow built-in shadowing instead of ignoring them - if is_graphql_reserved_name(&self.type_name) { - return Ok(()); - } - return Err(SingleFederationError::Internal { - message: format!("Type \"{}\" already exists in schema", self), - } - .into()); + bail!(r#"Type "{self}" already exists in schema"#); } schema .schema @@ -3815,14 +3706,7 @@ impl EnumTypeDefinitionPosition { pub(crate) fn pre_insert(&self, schema: &mut FederationSchema) -> Result<(), FederationError> { if schema.referencers.contains_type_name(&self.type_name) { - // TODO: Allow built-in shadowing instead of ignoring them - if is_graphql_reserved_name(&self.type_name) { - return Ok(()); - } - return Err(SingleFederationError::Internal { - message: format!("Type \"{}\" has already been pre-inserted", self), - } - .into()); + bail!(r#"Type "{self}" has already been pre-inserted"#); } schema .referencers @@ -3843,20 +3727,10 @@ impl EnumTypeDefinitionPosition { .into()); } if !schema.referencers.enum_types.contains_key(&self.type_name) { - return Err(SingleFederationError::Internal { - message: format!("Type \"{}\" has not been pre-inserted", self), - } - .into()); + bail!(r#"Type "{self}" has not been pre-inserted"#); } if schema.schema.types.contains_key(&self.type_name) { - // TODO: Allow built-in shadowing instead of ignoring them - if is_graphql_reserved_name(&self.type_name) { - return Ok(()); - } - return Err(SingleFederationError::Internal { - message: format!("Type \"{}\" already exists in schema", self), - } - .into()); + bail!(r#"Type "{self}" already exists in schema"#); } schema .schema @@ -4088,10 +3962,7 @@ impl EnumValueDefinitionPosition { .into()); } if self.try_get(&schema.schema).is_some() { - return Err(SingleFederationError::Internal { - message: format!("Enum value \"{}\" already exists in schema", self,), - } - .into()); + bail!(r#"Enum value "{self}" already exists in schema"#); } self.parent() .make_mut(&mut schema.schema)? @@ -4136,9 +4007,7 @@ impl EnumValueDefinitionPosition { referencers: &mut Referencers, ) -> Result<(), FederationError> { if is_graphql_reserved_name(&self.value_name) { - return Err(FederationError::internal(format!( - "Cannot insert reserved enum value \"{self}\"" - ))); + bail!(r#"Cannot insert reserved enum value "{self}""#); } validate_node_directives(value.directives.deref())?; for directive_reference in value.directives.iter() { @@ -4153,10 +4022,7 @@ impl EnumValueDefinitionPosition { referencers: &mut Referencers, ) -> Result<(), FederationError> { if is_graphql_reserved_name(&self.value_name) { - return Err(SingleFederationError::Internal { - message: format!("Cannot remove reserved enum value \"{}\"", self), - } - .into()); + bail!(r#"Cannot remove reserved enum value "{self}""#); } for directive_reference in value.directives.iter() { self.remove_directive_name_references(referencers, &directive_reference.name); @@ -4271,14 +4137,7 @@ impl InputObjectTypeDefinitionPosition { pub(crate) fn pre_insert(&self, schema: &mut FederationSchema) -> Result<(), FederationError> { if schema.referencers.contains_type_name(&self.type_name) { - // TODO: Allow built-in shadowing instead of ignoring them - if is_graphql_reserved_name(&self.type_name) { - return Ok(()); - } - return Err(SingleFederationError::Internal { - message: format!("Type \"{}\" has already been pre-inserted", self), - } - .into()); + bail!(r#"Type "{self}" has already been pre-inserted"#); } schema .referencers @@ -4306,20 +4165,10 @@ impl InputObjectTypeDefinitionPosition { .input_object_types .contains_key(&self.type_name) { - return Err(SingleFederationError::Internal { - message: format!("Type \"{}\" has not been pre-inserted", self), - } - .into()); + bail!(r#"Type "{self}" has not been pre-inserted"#); } if schema.schema.types.contains_key(&self.type_name) { - // TODO: Allow built-in shadowing instead of ignoring them - if is_graphql_reserved_name(&self.type_name) { - return Ok(()); - } - return Err(SingleFederationError::Internal { - message: format!("Type \"{}\" already exists in schema", self), - } - .into()); + bail!(r#"Type "{self}" already exists in schema"#); } schema .schema @@ -4578,10 +4427,7 @@ impl InputObjectFieldDefinitionPosition { .into()); } if self.try_get(&schema.schema).is_some() { - return Err(SingleFederationError::Internal { - message: format!("Input object field \"{}\" already exists in schema", self), - } - .into()); + bail!(r#"Input object field "{self}" already exists in schema"#); } self.parent() .make_mut(&mut schema.schema)? @@ -4643,10 +4489,7 @@ impl InputObjectFieldDefinitionPosition { referencers: &mut Referencers, ) -> Result<(), FederationError> { if is_graphql_reserved_name(&self.field_name) { - return Err(SingleFederationError::Internal { - message: format!("Cannot insert reserved input object field \"{}\"", self), - } - .into()); + bail!(r#"Cannot insert reserved input object field "{self}""#); } validate_node_directives(field.directives.deref())?; for directive_reference in field.directives.iter() { @@ -4661,10 +4504,7 @@ impl InputObjectFieldDefinitionPosition { referencers: &mut Referencers, ) -> Result<(), FederationError> { if is_graphql_reserved_name(&self.field_name) { - return Err(SingleFederationError::Internal { - message: format!("Cannot remove reserved input object field \"{}\"", self), - } - .into()); + bail!(r#"Cannot remove reserved input object field "{self}""#); } for directive_reference in field.directives.iter() { self.remove_directive_name_references(referencers, &directive_reference.name); @@ -4814,16 +4654,7 @@ impl DirectiveDefinitionPosition { .directives .contains_key(&self.directive_name) { - // TODO: Allow built-in shadowing instead of ignoring them - if is_graphql_reserved_name(&self.directive_name) - || GRAPHQL_BUILTIN_DIRECTIVE_NAMES.contains(&self.directive_name) - { - return Ok(()); - } - return Err(SingleFederationError::Internal { - message: format!("Directive \"{}\" has already been pre-inserted", self), - } - .into()); + bail!(r#"Directive "{self}" has already been pre-inserted"#); } schema .referencers @@ -4842,26 +4673,14 @@ impl DirectiveDefinitionPosition { .directives .contains_key(&self.directive_name) { - return Err(SingleFederationError::Internal { - message: format!("Directive \"{}\" has not been pre-inserted", self), - } - .into()); + bail!(r#"Directive "{self}" has not been pre-inserted"#); } if schema .schema .directive_definitions .contains_key(&self.directive_name) { - // TODO: Allow built-in shadowing instead of ignoring them - if is_graphql_reserved_name(&self.directive_name) - || GRAPHQL_BUILTIN_DIRECTIVE_NAMES.contains(&self.directive_name) - { - return Ok(()); - } - return Err(SingleFederationError::Internal { - message: format!("Directive \"{}\" already exists in schema", self), - } - .into()); + bail!(r#"Directive "{self}" already exists in schema"#); } schema .schema @@ -5069,10 +4888,7 @@ impl DirectiveArgumentDefinitionPosition { referencers: &mut Referencers, ) -> Result<(), FederationError> { if is_graphql_reserved_name(&self.argument_name) { - return Err(SingleFederationError::Internal { - message: format!("Cannot insert reserved directive argument \"{}\"", self), - } - .into()); + bail!(r#"Cannot insert reserved directive argument "{self}""#); } validate_node_directives(argument.directives.deref())?; for directive_reference in argument.directives.iter() { @@ -5087,10 +4903,7 @@ impl DirectiveArgumentDefinitionPosition { referencers: &mut Referencers, ) -> Result<(), FederationError> { if is_graphql_reserved_name(&self.argument_name) { - return Err(SingleFederationError::Internal { - message: format!("Cannot remove reserved directive argument \"{}\"", self), - } - .into()); + bail!(r#"Cannot remove reserved directive argument "{self}""#); } for directive_reference in argument.directives.iter() { self.remove_directive_name_references(referencers, &directive_reference.name); @@ -5198,29 +5011,7 @@ pub(crate) fn is_graphql_reserved_name(name: &str) -> bool { name.starts_with("__") } -lazy_static! { - static ref GRAPHQL_BUILTIN_SCALAR_NAMES: IndexSet = { - IndexSet::from_iter([ - name!("Int"), - name!("Float"), - name!("String"), - name!("Boolean"), - name!("ID"), - ]) - }; - static ref GRAPHQL_BUILTIN_DIRECTIVE_NAMES: IndexSet = { - IndexSet::from_iter([ - name!("include"), - name!("skip"), - name!("deprecated"), - name!("specifiedBy"), - name!("defer"), - ]) - }; - // This is static so that UnionTypenameFieldDefinitionPosition.field_name() can return `&Name`, - // like the other field_name() methods in this file. - pub(crate) static ref INTROSPECTION_TYPENAME_FIELD_NAME: Name = name!("__typename"); -} +pub(crate) static INTROSPECTION_TYPENAME_FIELD_NAME: Name = name!("__typename"); fn validate_component_directives( directives: &[Component], diff --git a/apollo-federation/src/supergraph/mod.rs b/apollo-federation/src/supergraph/mod.rs index bc8893f3d5..6ce40a6f48 100644 --- a/apollo-federation/src/supergraph/mod.rs +++ b/apollo-federation/src/supergraph/mod.rs @@ -339,6 +339,7 @@ fn extract_subgraphs_from_fed_2_supergraph( .schema() .directive_definitions .values() + .filter(|directive| !directive.is_built_in()) .filter_map(|directive_definition| { let executable_locations = directive_definition .locations From 4b9e0efe5f3e6ee42638197afbf088e517357956 Mon Sep 17 00:00:00 2001 From: Coenen Benjamin Date: Wed, 20 Nov 2024 14:09:01 +0100 Subject: [PATCH 51/77] add entity caching invalidation configuration metrics (#6286) Signed-off-by: Benjamin <5719034+bnjjj@users.noreply.github.com> --- .changesets/maint_bnjjj_feat_854.md | 5 +++++ apollo-router/src/configuration/metrics.rs | 4 +++- ...ion__metrics__test__metrics@entities.router.yaml.snap | 1 + .../configuration/testdata/metrics/entities.router.yaml | 9 +++++++-- 4 files changed, 16 insertions(+), 3 deletions(-) create mode 100644 .changesets/maint_bnjjj_feat_854.md diff --git a/.changesets/maint_bnjjj_feat_854.md b/.changesets/maint_bnjjj_feat_854.md new file mode 100644 index 0000000000..b06904f7bd --- /dev/null +++ b/.changesets/maint_bnjjj_feat_854.md @@ -0,0 +1,5 @@ +### Add entity caching invalidation configuration metrics ([PR #6286](https://github.com/apollographql/router/pull/6286)) + +Add metrics for our analytics to know if invalidation is enabled. + +By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/6286 \ No newline at end of file diff --git a/apollo-router/src/configuration/metrics.rs b/apollo-router/src/configuration/metrics.rs index 52ec64b384..6ea8121a69 100644 --- a/apollo-router/src/configuration/metrics.rs +++ b/apollo-router/src/configuration/metrics.rs @@ -318,7 +318,9 @@ impl InstrumentData { opt.subgraph.enabled, "$[?(@.subgraph.subgraphs..enabled)]", opt.subgraph.ttl, - "$[?(@.subgraph.all.ttl || @.subgraph.subgraphs..ttl)]" + "$[?(@.subgraph.all.ttl || @.subgraph.subgraphs..ttl)]", + opt.subgraph.invalidation.enabled, + "$[?(@.subgraph.all.invalidation.enabled || @.subgraph.subgraphs..invalidation.enabled)]" ); populate_config_instrument!( apollo.router.config.telemetry, diff --git a/apollo-router/src/configuration/snapshots/apollo_router__configuration__metrics__test__metrics@entities.router.yaml.snap b/apollo-router/src/configuration/snapshots/apollo_router__configuration__metrics__test__metrics@entities.router.yaml.snap index 9b586a2b76..1285a6de53 100644 --- a/apollo-router/src/configuration/snapshots/apollo_router__configuration__metrics__test__metrics@entities.router.yaml.snap +++ b/apollo-router/src/configuration/snapshots/apollo_router__configuration__metrics__test__metrics@entities.router.yaml.snap @@ -9,4 +9,5 @@ expression: "&metrics.non_zero()" attributes: opt.enabled: true opt.subgraph.enabled: true + opt.subgraph.invalidation.enabled: true opt.subgraph.ttl: true diff --git a/apollo-router/src/configuration/testdata/metrics/entities.router.yaml b/apollo-router/src/configuration/testdata/metrics/entities.router.yaml index e2cbd0ee04..2382453c33 100644 --- a/apollo-router/src/configuration/testdata/metrics/entities.router.yaml +++ b/apollo-router/src/configuration/testdata/metrics/entities.router.yaml @@ -9,10 +9,15 @@ preview_entity_cache: urls: [ "redis://localhost:6379" ] timeout: 5ms ttl: 60s - enabled: true + invalidation: + enabled: true + shared_key: "invalidate" subgraphs: accounts: enabled: false products: - ttl: 120s \ No newline at end of file + ttl: 120s + invalidation: + enabled: true + shared_key: "invalidate" \ No newline at end of file From 382fbe0a3009294374ebd62d82d8b61569ec8e55 Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Wed, 20 Nov 2024 17:53:10 +0200 Subject: [PATCH 52/77] fix(file_upload): remove placeholders from query variables (#6293) Co-authored-by: Bryn Cooke --- ...ix_fix_file_upload_variable_placeholder.md | 7 + apollo-router/src/plugins/file_uploads/mod.rs | 4 +- .../tests/integration/file_upload.rs | 128 +++++++++++++++++- 3 files changed, 132 insertions(+), 7 deletions(-) create mode 100644 .changesets/fix_fix_file_upload_variable_placeholder.md diff --git a/.changesets/fix_fix_file_upload_variable_placeholder.md b/.changesets/fix_fix_file_upload_variable_placeholder.md new file mode 100644 index 0000000000..e656525589 --- /dev/null +++ b/.changesets/fix_fix_file_upload_variable_placeholder.md @@ -0,0 +1,7 @@ +### File Uploads: Remove Placeholders from Query Variables ([PR #6293](https://github.com/apollographql/router/pull/6293)) + +Fixed an issue where file upload query variables in subgraph requests contained internal placeholders. +According to the [GraphQL Multipart Request Spec](https://github.com/jaydenseric/graphql-multipart-request-spec?tab=readme-ov-file#multipart-form-field-structure), these variables should be set to null. +This fix ensures that the Router complies with the specification and improves compatibility with subgraphs handling file uploads. + +By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6293 diff --git a/apollo-router/src/plugins/file_uploads/mod.rs b/apollo-router/src/plugins/file_uploads/mod.rs index fb44aa6b25..6932495ebc 100644 --- a/apollo-router/src/plugins/file_uploads/mod.rs +++ b/apollo-router/src/plugins/file_uploads/mod.rs @@ -254,7 +254,9 @@ fn replace_value_at_path<'a>( // Removes value at path. fn remove_value_at_path<'a>(variables: &'a mut json_ext::Object, path: &'a [String]) { - let _ = get_value_at_path(variables, path).take(); + if let Some(v) = get_value_at_path(variables, path) { + *v = serde_json_bytes::Value::Null; + } } fn get_value_at_path<'a>( diff --git a/apollo-router/tests/integration/file_upload.rs b/apollo-router/tests/integration/file_upload.rs index add9e81a90..fd272f9d28 100644 --- a/apollo-router/tests/integration/file_upload.rs +++ b/apollo-router/tests/integration/file_upload.rs @@ -22,6 +22,124 @@ macro_rules! make_handler { } } +#[tokio::test(flavor = "multi_thread")] +async fn it_uploads_file_to_subgraph() -> Result<(), BoxError> { + use reqwest::multipart::Form; + use reqwest::multipart::Part; + + const FILE: &str = "Hello, world!"; + const FILE_NAME: &str = "example.txt"; + + let request = Form::new() + .part( + "operations", + Part::text( + serde_json::json!({ + "query": "mutation SomeMutation($file: Upload) { + file: singleUpload(file: $file) { filename body } + }", + "variables": { "file": null }, + }) + .to_string(), + ), + ) + .part( + "map", + Part::text(serde_json::json!({ "0": ["variables.file"] }).to_string()), + ) + .part("0", Part::text(FILE).file_name(FILE_NAME)); + + async fn subgraph_handler( + mut request: http::Request, + ) -> impl axum::response::IntoResponse { + let boundary = request + .headers() + .get(CONTENT_TYPE) + .and_then(|v| multer::parse_boundary(v.to_str().ok()?).ok()) + .expect("subgraph request should have valid Content-Type header"); + let mut multipart = multer::Multipart::new(request.body_mut(), boundary); + + let operations_field = multipart + .next_field() + .await + .ok() + .flatten() + .expect("subgraph request should have valid `operations` field"); + assert_eq!(operations_field.name(), Some("operations")); + let operations: helper::Operation = + serde_json::from_slice(&operations_field.bytes().await.unwrap()).unwrap(); + insta::assert_json_snapshot!(operations, @r#" + { + "query": "mutation SomeMutation__uploads__0($file:Upload){file:singleUpload(file:$file){filename body}}", + "variables": { + "file": null + } + } + "#); + + let map_field = multipart + .next_field() + .await + .ok() + .flatten() + .expect("subgraph request should have valid `map` field"); + assert_eq!(map_field.name(), Some("map")); + let map: BTreeMap> = + serde_json::from_slice(&map_field.bytes().await.unwrap()).unwrap(); + insta::assert_json_snapshot!(map, @r#" + { + "0": [ + "variables.file" + ] + } + "#); + + let file_field = multipart + .next_field() + .await + .ok() + .flatten() + .expect("subgraph request should have file field"); + + ( + http::StatusCode::OK, + axum::Json(serde_json::json!({ + "data": { + "file": { + "filename": file_field.file_name().unwrap(), + "body": file_field.text().await.unwrap(), + }, + } + })), + ) + } + + // Run the test + helper::FileUploadTestServer::builder() + .config(FILE_CONFIG) + .handler(make_handler!(subgraph_handler)) + .request(request) + .subgraph_mapping("uploads", "/") + .build() + .run_test(|response| { + // FIXME: workaround to not update bellow snapshot if one of snapshots inside 'subgraph_handler' fails + // This would be fixed if subgraph shapshots are moved out of 'subgraph_handler' + assert_eq!(response.errors.len(), 0); + + insta::assert_json_snapshot!(response, @r###" + { + "data": { + "file": { + "filename": "example.txt", + "body": "Hello, world!" + } + } + } + "###); + }) + .await +} + #[tokio::test(flavor = "multi_thread")] async fn it_uploads_a_single_file() -> Result<(), BoxError> { const FILE: &str = "Hello, world!"; @@ -1043,7 +1161,7 @@ mod helper { pub body: Option, } - #[derive(Serialize, Deserialize)] + #[derive(Debug, Serialize, Deserialize)] pub struct Operation { // TODO: Can we verify that this is a valid graphql query? query: String, @@ -1168,10 +1286,8 @@ mod helper { return Err(FileUploadError::UnexpectedFile); } - let field_name: String = map - .into_keys() - .take(1) - .next() + let (field_name, _) = map + .first_key_value() .ok_or(FileUploadError::MissingMapping)?; // Extract the single expected file @@ -1181,7 +1297,7 @@ mod helper { .await? .ok_or(FileUploadError::MissingFile(field_name.clone()))?; - let file_name = f.file_name().unwrap_or(&field_name).to_string(); + let file_name = f.file_name().unwrap_or(field_name).to_string(); let body = f.bytes().await?; Upload { From 24c4998bd13c9e8d0c0526a13c18cdbd0bea2f37 Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Wed, 20 Nov 2024 18:36:26 +0200 Subject: [PATCH 53/77] Add `extensions.service` for all subgraph errors (#6191) --- .changesets/feat_error_extensions_service.md | 29 ++++ ...factory__tests__defer_is_not_buffered.snap | 3 +- ...ins__cache__tests__missing_entities-2.snap | 5 +- .../src/plugins/include_subgraph_errors.rs | 53 ++++--- ..._from_primary_on_deferred_responses-2.snap | 5 +- ...tests__errors_on_deferred_responses-2.snap | 5 +- ...ts__errors_on_incremental_responses-2.snap | 10 +- ...aph__tests__errors_on_nullified_paths.snap | 3 +- ...__supergraph__tests__missing_entities.snap | 5 +- apollo-router/tests/integration/batching.rs | 14 ++ ...raffic_shaping__subgraph_rate_limit-2.snap | 2 +- ...on__traffic_shaping__subgraph_timeout.snap | 2 +- .../tests/integration/subgraph_response.rs | 132 +++++++++++++++++- ...__set_context_dependent_fetch_failure.snap | 5 +- ...__set_context_unrelated_fetch_failure.snap | 5 +- .../subgraph-error-inclusion.mdx | 18 +++ 16 files changed, 259 insertions(+), 37 deletions(-) create mode 100644 .changesets/feat_error_extensions_service.md diff --git a/.changesets/feat_error_extensions_service.md b/.changesets/feat_error_extensions_service.md new file mode 100644 index 0000000000..f182e44ea8 --- /dev/null +++ b/.changesets/feat_error_extensions_service.md @@ -0,0 +1,29 @@ +### Add `extensions.service` for all subgraph errors ([PR #6191](https://github.com/apollographql/router/pull/6191)) + +If `include_subgraph_errors` is `true` for a particular subgraph, all errors originating in this subgraph will have the subgraph's name exposed as a `service` extension. + +For example, if subgraph errors are enabled, like so: +```yaml title="router.yaml" +include_subgraph_errors: + all: true # Propagate errors from all subgraphs +``` +Note: This option is enabled by default in the [dev mode](./configuration/overview#dev-mode-defaults). + +And this `products` subgraph returns an error, it will have a `service` extension: + +```json +{ + "data": null, + "errors": [ + { + "message": "Invalid product ID", + "path": [], + "extensions": { + "service": "products" + } + } + ] +} +``` + +By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6191 \ No newline at end of file diff --git a/apollo-router/src/axum_factory/snapshots/apollo_router__axum_factory__tests__defer_is_not_buffered.snap b/apollo-router/src/axum_factory/snapshots/apollo_router__axum_factory__tests__defer_is_not_buffered.snap index ece5fd3c9f..6ae04241f1 100644 --- a/apollo-router/src/axum_factory/snapshots/apollo_router__axum_factory__tests__defer_is_not_buffered.snap +++ b/apollo-router/src/axum_factory/snapshots/apollo_router__axum_factory__tests__defer_is_not_buffered.snap @@ -26,7 +26,8 @@ expression: parts "@" ], "extensions": { - "code": "FETCH_ERROR" + "code": "FETCH_ERROR", + "service": "reviews" } } ], diff --git a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__missing_entities-2.snap b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__missing_entities-2.snap index 9798af179e..0944c313df 100644 --- a/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__missing_entities-2.snap +++ b/apollo-router/src/plugins/cache/snapshots/apollo_router__plugins__cache__tests__missing_entities-2.snap @@ -28,7 +28,10 @@ expression: response "currentUser", "allOrganizations", 2 - ] + ], + "extensions": { + "service": "orga" + } } ] } diff --git a/apollo-router/src/plugins/include_subgraph_errors.rs b/apollo-router/src/plugins/include_subgraph_errors.rs index 3b399e0151..5641d0a506 100644 --- a/apollo-router/src/plugins/include_subgraph_errors.rs +++ b/apollo-router/src/plugins/include_subgraph_errors.rs @@ -42,36 +42,47 @@ impl Plugin for IncludeSubgraphErrors { } fn subgraph_service(&self, name: &str, service: subgraph::BoxService) -> subgraph::BoxService { - // Search for subgraph in our configured subgraph map. - // If we can't find it, use the "all" value - if !*self.config.subgraphs.get(name).unwrap_or(&self.config.all) { - let sub_name_response = name.to_string(); - let sub_name_error = name.to_string(); - return service - .map_response(move |mut response: SubgraphResponse| { - if !response.response.body().errors.is_empty() { + // Search for subgraph in our configured subgraph map. If we can't find it, use the "all" value + let include_subgraph_errors = *self.config.subgraphs.get(name).unwrap_or(&self.config.all); + + let sub_name_response = name.to_string(); + let sub_name_error = name.to_string(); + return service + .map_response(move |mut response: SubgraphResponse| { + let errors = &mut response.response.body_mut().errors; + if !errors.is_empty() { + if include_subgraph_errors { + for error in errors.iter_mut() { + error + .extensions + .entry("service") + .or_insert(sub_name_response.clone().into()); + } + } else { tracing::info!("redacted subgraph({sub_name_response}) errors"); - for error in response.response.body_mut().errors.iter_mut() { + for error in errors.iter_mut() { error.message = REDACTED_ERROR_MESSAGE.to_string(); error.extensions = Object::default(); } } - response - }) - // _error to stop clippy complaining about unused assignments... - .map_err(move |mut _error: BoxError| { + } + + response + }) + .map_err(move |error: BoxError| { + if include_subgraph_errors { + error + } else { // Create a redacted error to replace whatever error we have tracing::info!("redacted subgraph({sub_name_error}) error"); - _error = Box::new(crate::error::FetchError::SubrequestHttpError { + Box::new(crate::error::FetchError::SubrequestHttpError { status_code: None, service: "redacted".to_string(), reason: "redacted".to_string(), - }); - _error - }) - .boxed(); - } - service + }) + } + }) + .boxed(); } } @@ -104,7 +115,7 @@ mod test { use crate::Configuration; static UNREDACTED_PRODUCT_RESPONSE: Lazy = Lazy::new(|| { - Bytes::from_static(r#"{"data":{"topProducts":null},"errors":[{"message":"couldn't find mock for query {\"query\":\"query($first: Int) { topProducts(first: $first) { __typename upc } }\",\"variables\":{\"first\":2}}","path":[],"extensions":{"test":"value","code":"FETCH_ERROR"}}]}"#.as_bytes()) + Bytes::from_static(r#"{"data":{"topProducts":null},"errors":[{"message":"couldn't find mock for query {\"query\":\"query($first: Int) { topProducts(first: $first) { __typename upc } }\",\"variables\":{\"first\":2}}","path":[],"extensions":{"test":"value","code":"FETCH_ERROR","service":"products"}}]}"#.as_bytes()) }); static REDACTED_PRODUCT_RESPONSE: Lazy = Lazy::new(|| { diff --git a/apollo-router/src/services/supergraph/snapshots/apollo_router__services__supergraph__tests__errors_from_primary_on_deferred_responses-2.snap b/apollo-router/src/services/supergraph/snapshots/apollo_router__services__supergraph__tests__errors_from_primary_on_deferred_responses-2.snap index 36f064b496..40f678bb4f 100644 --- a/apollo-router/src/services/supergraph/snapshots/apollo_router__services__supergraph__tests__errors_from_primary_on_deferred_responses-2.snap +++ b/apollo-router/src/services/supergraph/snapshots/apollo_router__services__supergraph__tests__errors_from_primary_on_deferred_responses-2.snap @@ -24,7 +24,10 @@ expression: stream.next_response().await.unwrap() "path": [ "computer", "errorField" - ] + ], + "extensions": { + "service": "computers" + } } ] } diff --git a/apollo-router/src/services/supergraph/snapshots/apollo_router__services__supergraph__tests__errors_on_deferred_responses-2.snap b/apollo-router/src/services/supergraph/snapshots/apollo_router__services__supergraph__tests__errors_on_deferred_responses-2.snap index d487599dc5..6cfe12e7a7 100644 --- a/apollo-router/src/services/supergraph/snapshots/apollo_router__services__supergraph__tests__errors_on_deferred_responses-2.snap +++ b/apollo-router/src/services/supergraph/snapshots/apollo_router__services__supergraph__tests__errors_on_deferred_responses-2.snap @@ -17,7 +17,10 @@ expression: stream.next_response().await.unwrap() "message": "error user 0", "path": [ "currentUser" - ] + ], + "extensions": { + "service": "user" + } } ] } diff --git a/apollo-router/src/services/supergraph/snapshots/apollo_router__services__supergraph__tests__errors_on_incremental_responses-2.snap b/apollo-router/src/services/supergraph/snapshots/apollo_router__services__supergraph__tests__errors_on_incremental_responses-2.snap index c36f465d70..8cac0e7164 100644 --- a/apollo-router/src/services/supergraph/snapshots/apollo_router__services__supergraph__tests__errors_on_incremental_responses-2.snap +++ b/apollo-router/src/services/supergraph/snapshots/apollo_router__services__supergraph__tests__errors_on_incremental_responses-2.snap @@ -23,7 +23,10 @@ expression: stream.next_response().await.unwrap() "activeOrganization", "suborga", 0 - ] + ], + "extensions": { + "service": "orga" + } } ] }, @@ -56,7 +59,10 @@ expression: stream.next_response().await.unwrap() "activeOrganization", "suborga", 2 - ] + ], + "extensions": { + "service": "orga" + } } ] } diff --git a/apollo-router/src/services/supergraph/snapshots/apollo_router__services__supergraph__tests__errors_on_nullified_paths.snap b/apollo-router/src/services/supergraph/snapshots/apollo_router__services__supergraph__tests__errors_on_nullified_paths.snap index bf618438ad..4299132063 100644 --- a/apollo-router/src/services/supergraph/snapshots/apollo_router__services__supergraph__tests__errors_on_nullified_paths.snap +++ b/apollo-router/src/services/supergraph/snapshots/apollo_router__services__supergraph__tests__errors_on_nullified_paths.snap @@ -20,7 +20,8 @@ expression: stream.next_response().await.unwrap() "bar" ], "extensions": { - "code": "NOT_FOUND" + "code": "NOT_FOUND", + "service": "S2" } } ] diff --git a/apollo-router/src/services/supergraph/snapshots/apollo_router__services__supergraph__tests__missing_entities.snap b/apollo-router/src/services/supergraph/snapshots/apollo_router__services__supergraph__tests__missing_entities.snap index a4366f1d9a..a046e3aa13 100644 --- a/apollo-router/src/services/supergraph/snapshots/apollo_router__services__supergraph__tests__missing_entities.snap +++ b/apollo-router/src/services/supergraph/snapshots/apollo_router__services__supergraph__tests__missing_entities.snap @@ -18,7 +18,10 @@ expression: stream.next_response().await.unwrap() "path": [ "currentUser", "activeOrganization" - ] + ], + "extensions": { + "service": "orga" + } } ] } diff --git a/apollo-router/tests/integration/batching.rs b/apollo-router/tests/integration/batching.rs index 071ca5cb7a..7998a21528 100644 --- a/apollo-router/tests/integration/batching.rs +++ b/apollo-router/tests/integration/batching.rs @@ -147,6 +147,8 @@ async fn it_batches_with_errors_in_single_graph() -> Result<(), BoxError> { - errors: - message: expected error in A path: [] + extensions: + service: a - data: entryA: index: 2 @@ -200,9 +202,13 @@ async fn it_batches_with_errors_in_multi_graph() -> Result<(), BoxError> { - errors: - message: expected error in A path: [] + extensions: + service: a - errors: - message: expected error in B path: [] + extensions: + service: b - data: entryA: index: 2 @@ -256,6 +262,7 @@ async fn it_handles_short_timeouts() -> Result<(), BoxError> { path: [] extensions: code: REQUEST_TIMEOUT + service: b - data: entryA: index: 1 @@ -264,6 +271,7 @@ async fn it_handles_short_timeouts() -> Result<(), BoxError> { path: [] extensions: code: REQUEST_TIMEOUT + service: b "###); } @@ -331,16 +339,19 @@ async fn it_handles_indefinite_timeouts() -> Result<(), BoxError> { path: [] extensions: code: REQUEST_TIMEOUT + service: b - errors: - message: Request timed out path: [] extensions: code: REQUEST_TIMEOUT + service: b - errors: - message: Request timed out path: [] extensions: code: REQUEST_TIMEOUT + service: b "###); } @@ -568,6 +579,7 @@ async fn it_handles_cancelled_by_coprocessor() -> Result<(), BoxError> { path: [] extensions: code: ERR_NOT_ALLOWED + service: a - data: entryB: index: 0 @@ -576,6 +588,7 @@ async fn it_handles_cancelled_by_coprocessor() -> Result<(), BoxError> { path: [] extensions: code: ERR_NOT_ALLOWED + service: a - data: entryB: index: 1 @@ -725,6 +738,7 @@ async fn it_handles_single_request_cancelled_by_coprocessor() -> Result<(), BoxE path: [] extensions: code: ERR_NOT_ALLOWED + service: a - data: entryB: index: 2 diff --git a/apollo-router/tests/integration/snapshots/integration_tests__integration__traffic_shaping__subgraph_rate_limit-2.snap b/apollo-router/tests/integration/snapshots/integration_tests__integration__traffic_shaping__subgraph_rate_limit-2.snap index 07df294289..83a52acd05 100644 --- a/apollo-router/tests/integration/snapshots/integration_tests__integration__traffic_shaping__subgraph_rate_limit-2.snap +++ b/apollo-router/tests/integration/snapshots/integration_tests__integration__traffic_shaping__subgraph_rate_limit-2.snap @@ -2,4 +2,4 @@ source: apollo-router/tests/integration/traffic_shaping.rs expression: response --- -"{\"data\":null,\"errors\":[{\"message\":\"Your request has been rate limited\",\"path\":[],\"extensions\":{\"code\":\"REQUEST_RATE_LIMITED\"}}]}" +"{\"data\":null,\"errors\":[{\"message\":\"Your request has been rate limited\",\"path\":[],\"extensions\":{\"code\":\"REQUEST_RATE_LIMITED\",\"service\":\"products\"}}]}" diff --git a/apollo-router/tests/integration/snapshots/integration_tests__integration__traffic_shaping__subgraph_timeout.snap b/apollo-router/tests/integration/snapshots/integration_tests__integration__traffic_shaping__subgraph_timeout.snap index 407674dfff..0364f2b734 100644 --- a/apollo-router/tests/integration/snapshots/integration_tests__integration__traffic_shaping__subgraph_timeout.snap +++ b/apollo-router/tests/integration/snapshots/integration_tests__integration__traffic_shaping__subgraph_timeout.snap @@ -2,4 +2,4 @@ source: apollo-router/tests/integration/traffic_shaping.rs expression: response --- -"{\"data\":null,\"errors\":[{\"message\":\"Request timed out\",\"path\":[],\"extensions\":{\"code\":\"REQUEST_TIMEOUT\"}}]}" +"{\"data\":null,\"errors\":[{\"message\":\"Request timed out\",\"path\":[],\"extensions\":{\"code\":\"REQUEST_TIMEOUT\",\"service\":\"products\"}}]}" diff --git a/apollo-router/tests/integration/subgraph_response.rs b/apollo-router/tests/integration/subgraph_response.rs index 52fc56fa27..e37a0da067 100644 --- a/apollo-router/tests/integration/subgraph_response.rs +++ b/apollo-router/tests/integration/subgraph_response.rs @@ -81,6 +81,125 @@ async fn test_subgraph_returning_different_typename_on_query_root() -> Result<() Ok(()) } +#[tokio::test(flavor = "multi_thread")] +async fn test_valid_extensions_service_for_subgraph_error() -> Result<(), BoxError> { + let mut router = IntegrationTest::builder() + .config(CONFIG) + .responder(ResponseTemplate::new(200).set_body_json(json!({ + "data": { "topProducts": null }, + "errors": [{ + "message": "Some error on subgraph", + "path": ["topProducts"] + }] + }))) + .build() + .await; + + router.start().await; + router.assert_started().await; + + let (_trace_id, response) = router + .execute_query(&json!({ "query": "{ topProducts { name } }" })) + .await; + assert_eq!(response.status(), 200); + assert_eq!( + response.json::().await?, + json!({ + "data": { "topProducts": null }, + "errors": [{ + "message": "Some error on subgraph", + "path":["topProducts"], + "extensions": { + "service": "products" + } + }] + }) + ); + + router.graceful_shutdown().await; + Ok(()) +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_valid_extensions_service_is_preserved_for_subgraph_error() -> Result<(), BoxError> { + let mut router = IntegrationTest::builder() + .config(CONFIG) + .responder(ResponseTemplate::new(200).set_body_json(json!({ + "data": { "topProducts": null }, + "errors": [{ + "message": "Some error on subgraph", + "path": ["topProducts"], + "extensions": { + "service": 42, + } + }] + }))) + .build() + .await; + + router.start().await; + router.assert_started().await; + + let (_trace_id, response) = router + .execute_query(&json!({ "query": "{ topProducts { name } }" })) + .await; + assert_eq!(response.status(), 200); + assert_eq!( + response.json::().await?, + json!({ + "data": { "topProducts": null }, + "errors": [{ + "message": "Some error on subgraph", + "path":["topProducts"], + "extensions": { + "service": 42, + } + }] + }) + ); + + router.graceful_shutdown().await; + Ok(()) +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_valid_extensions_service_for_invalid_subgraph_response() -> Result<(), BoxError> { + let mut router = IntegrationTest::builder() + .config(CONFIG) + .responder(ResponseTemplate::new(200)) + .build() + .await; + + router.start().await; + router.assert_started().await; + + let (_trace_id, response) = router + .execute_query(&json!({ "query": "{ topProducts { name } }" })) + .await; + assert_eq!(response.status(), 200); + assert_eq!( + response.json::().await?, + json!({ + "data": null, + "errors": [ + { + "message": "HTTP fetch failed from 'products': subgraph response does not contain 'content-type' header; expected content-type: application/json or content-type: application/graphql-response+json", + "path": [], + "extensions": { + "code": "SUBREQUEST_HTTP_ERROR", + "service": "products", + "reason": "subgraph response does not contain 'content-type' header; expected content-type: application/json or content-type: application/graphql-response+json", + "http": { "status": 200 } + } + } + ] + }) + ); + + router.graceful_shutdown().await; + Ok(()) +} + #[tokio::test(flavor = "multi_thread")] async fn test_valid_error_locations() -> Result<(), BoxError> { let mut router = IntegrationTest::builder() @@ -116,7 +235,8 @@ async fn test_valid_error_locations() -> Result<(), BoxError> { { "line": 1, "column": 2 }, { "line": 3, "column": 4 }, ], - "path":["topProducts"] + "path":["topProducts"], + "extensions": { "service": "products" } }] }) ); @@ -153,7 +273,8 @@ async fn test_empty_error_locations() -> Result<(), BoxError> { "data": { "topProducts": null }, "errors": [{ "message":"Some error on subgraph", - "path":["topProducts"] + "path":["topProducts"], + "extensions": { "service": "products" } }] }) ); @@ -195,6 +316,7 @@ async fn test_invalid_error_locations() -> Result<(), BoxError> { "service": "products", "reason": "invalid `locations` within error: invalid type: boolean `true`, expected u32", "code": "SUBREQUEST_MALFORMED_RESPONSE", + "service": "products" } }] }) @@ -232,7 +354,8 @@ async fn test_invalid_error_locations_with_single_negative_one_location() -> Res "data": { "topProducts": null }, "errors": [{ "message":"Some error on subgraph", - "path":["topProducts"] + "path":["topProducts"], + "extensions": { "service": "products" } }] }) ); @@ -277,7 +400,8 @@ async fn test_invalid_error_locations_contains_negative_one_location() -> Result { "line": 1, "column": 2 }, { "line": 3, "column": 4 }, ], - "path":["topProducts"] + "path":["topProducts"], + "extensions": { "service": "products" } }] }) ); diff --git a/apollo-router/tests/snapshots/set_context__set_context_dependent_fetch_failure.snap b/apollo-router/tests/snapshots/set_context__set_context_dependent_fetch_failure.snap index 4c44587cdd..67390167e7 100644 --- a/apollo-router/tests/snapshots/set_context__set_context_dependent_fetch_failure.snap +++ b/apollo-router/tests/snapshots/set_context__set_context_dependent_fetch_failure.snap @@ -16,7 +16,10 @@ expression: response "path": [ "t", "u" - ] + ], + "extensions": { + "service": "Subgraph1" + } } ], "extensions": { diff --git a/apollo-router/tests/snapshots/set_context__set_context_unrelated_fetch_failure.snap b/apollo-router/tests/snapshots/set_context__set_context_unrelated_fetch_failure.snap index 4f28e80419..3232f642c0 100644 --- a/apollo-router/tests/snapshots/set_context__set_context_unrelated_fetch_failure.snap +++ b/apollo-router/tests/snapshots/set_context__set_context_unrelated_fetch_failure.snap @@ -10,7 +10,10 @@ expression: response "path": [ "t", "u" - ] + ], + "extensions": { + "service": "Subgraph2" + } } ], "extensions": { diff --git a/docs/source/routing/observability/subgraph-error-inclusion.mdx b/docs/source/routing/observability/subgraph-error-inclusion.mdx index d991a3e710..ee28a0672d 100644 --- a/docs/source/routing/observability/subgraph-error-inclusion.mdx +++ b/docs/source/routing/observability/subgraph-error-inclusion.mdx @@ -31,3 +31,21 @@ To report the subgraph errors to GraphOS that is a separate configuration that i ## Logging GraphQL request errors To log the GraphQL error responses (i.e. messages returned in the GraphQL `errors` array) from the router, see the [logging configuration documentation](/router/configuration/telemetry/exporters/logging/overview). +## Exposing subgraph name through error extensions +If `include_subgraph_errors` is `true` for a particular subgraph, all errors originating in this subgraph will have the subgraph's name exposed as a `service` extension. + +For example, if subgraph errors are enabled for the `products` subgraph and this subgraph returns an error, it will have a `service` extension: +```json +{ + "data": null, + "errors": [ + { + "message": "Invalid product ID", + "path": [], + "extensions": { + "service": "products", + } + } + ] +} +``` From 02c9965e9847d21dceb8e085a37ec2a4a12f6fee Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 20 Nov 2024 18:51:54 +0200 Subject: [PATCH 54/77] chore: Update release script to use new docs locations These were introduced in https://github.com/apollographql/router/pull/6248 --- xtask/src/commands/release.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xtask/src/commands/release.rs b/xtask/src/commands/release.rs index 51066382f9..db80637fc5 100644 --- a/xtask/src/commands/release.rs +++ b/xtask/src/commands/release.rs @@ -281,12 +281,12 @@ impl Prepare { fn update_docs(&self, version: &str) -> Result<()> { println!("updating docs"); replace_in_file!( - "./docs/source/containerization/docker.mdx", + "./docs/source/routing/self-hosted/containerization/docker.mdx", "with your chosen version. e.g.: `v[^`]+`", format!("with your chosen version. e.g.: `v{version}`") ); replace_in_file!( - "./docs/source/containerization/kubernetes.mdx", + "./docs/source/routing/self-hosted/containerization/kubernetes.mdx", "https://github.com/apollographql/router/tree/[^/]+/helm/chart/router", format!("https://github.com/apollographql/router/tree/v{version}/helm/chart/router") ); @@ -309,7 +309,7 @@ impl Prepare { )?; replace_in_file!( - "./docs/source/containerization/kubernetes.mdx", + "./docs/source/routing/self-hosted/containerization/kubernetes.mdx", "^```yaml\n---\n# Source: router/templates/serviceaccount.yaml(.|\n)+?```", format!("```yaml\n{}\n```", helm_chart.trim()) ); From f05b73148975b472964dec07a6b45af7ec110c86 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 20 Nov 2024 18:56:18 +0200 Subject: [PATCH 55/77] prep release: v1.58.0-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.template.toml | 2 +- .../templates/base/xtask/Cargo.template.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 | 6 +- licenses.html | 464 +++++++++++++++++- scripts/install.sh | 2 +- 14 files changed, 480 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b8d2d105bd..8428ccc8a5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -178,7 +178,7 @@ dependencies = [ [[package]] name = "apollo-federation" -version = "1.57.1" +version = "1.58.0-rc.0" dependencies = [ "apollo-compiler", "derive_more", @@ -230,7 +230,7 @@ dependencies = [ [[package]] name = "apollo-router" -version = "1.57.1" +version = "1.58.0-rc.0" dependencies = [ "access-json", "ahash", @@ -398,7 +398,7 @@ dependencies = [ [[package]] name = "apollo-router-benchmarks" -version = "1.57.1" +version = "1.58.0-rc.0" dependencies = [ "apollo-parser", "apollo-router", @@ -414,7 +414,7 @@ dependencies = [ [[package]] name = "apollo-router-scaffold" -version = "1.57.1" +version = "1.58.0-rc.0" dependencies = [ "anyhow", "cargo-scaffold", diff --git a/apollo-federation/Cargo.toml b/apollo-federation/Cargo.toml index c93e2d79d0..261f5cea22 100644 --- a/apollo-federation/Cargo.toml +++ b/apollo-federation/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-federation" -version = "1.57.1" +version = "1.58.0-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 d26748c696..1a516d25f8 100644 --- a/apollo-router-benchmarks/Cargo.toml +++ b/apollo-router-benchmarks/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router-benchmarks" -version = "1.57.1" +version = "1.58.0-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 63bf887d7f..0e35a1180e 100644 --- a/apollo-router-scaffold/Cargo.toml +++ b/apollo-router-scaffold/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router-scaffold" -version = "1.57.1" +version = "1.58.0-rc.0" authors = ["Apollo Graph, Inc. "] edition = "2021" license = "Elastic-2.0" diff --git a/apollo-router-scaffold/templates/base/Cargo.template.toml b/apollo-router-scaffold/templates/base/Cargo.template.toml index 6b9873bf75..0a82428fc1 100644 --- a/apollo-router-scaffold/templates/base/Cargo.template.toml +++ b/apollo-router-scaffold/templates/base/Cargo.template.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.57.1" +apollo-router = "1.58.0-rc.0" {{/if}} {{/if}} async-trait = "0.1.52" diff --git a/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml b/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml index f58bd86237..1fb3c2ce4a 100644 --- a/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml +++ b/apollo-router-scaffold/templates/base/xtask/Cargo.template.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.57.1" } +apollo-router-scaffold = { git = "https://github.com/apollographql/router.git", tag = "v1.58.0-rc.0" } {{/if}} {{/if}} anyhow = "1.0.58" diff --git a/apollo-router/Cargo.toml b/apollo-router/Cargo.toml index 6c7e06a6d0..77f41071b5 100644 --- a/apollo-router/Cargo.toml +++ b/apollo-router/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router" -version = "1.57.1" +version = "1.58.0-rc.0" authors = ["Apollo Graph, Inc. "] repository = "https://github.com/apollographql/router/" documentation = "https://docs.rs/apollo-router" @@ -66,7 +66,7 @@ features = ["docs_rs"] access-json = "0.1.0" anyhow = "1.0.86" apollo-compiler.workspace = true -apollo-federation = { path = "../apollo-federation", version = "=1.57.1" } +apollo-federation = { path = "../apollo-federation", version = "=1.58.0-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 db46f878fb..6ce00496e3 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.57.1 + image: ghcr.io/apollographql/router:v1.58.0-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 a38d04b6ba..5d07c9c245 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.57.1 + image: ghcr.io/apollographql/router:v1.58.0-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 366bff5506..00ae0bd2e0 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.57.1 + image: ghcr.io/apollographql/router:v1.58.0-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 9d7c28d3d0..ef9327ee8b 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.57.1 +version: 1.58.0-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.57.1" +appVersion: "v1.58.0-rc.0" diff --git a/helm/chart/router/README.md b/helm/chart/router/README.md index 6dd2aaea77..12e17400da 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.57.1](https://img.shields.io/badge/Version-1.57.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.57.1](https://img.shields.io/badge/AppVersion-v1.57.1-informational?style=flat-square) +![Version: 1.58.0-rc.0](https://img.shields.io/badge/Version-1.58.0--rc.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.58.0-rc.0](https://img.shields.io/badge/AppVersion-v1.58.0--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.57.1 +helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0-rc.0 ``` ## Install Chart @@ -19,7 +19,7 @@ helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.57.1 **Important:** only helm3 is supported ```console -helm upgrade --install [RELEASE_NAME] oci://ghcr.io/apollographql/helm-charts/router --version 1.57.1 --values my-values.yaml +helm upgrade --install [RELEASE_NAME] oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0-rc.0 --values my-values.yaml ``` _See [configuration](#configuration) below._ diff --git a/licenses.html b/licenses.html index 01b9b1d8ef..37ceccad5d 100644 --- a/licenses.html +++ b/licenses.html @@ -44,16 +44,17 @@

      Third Party Licenses

      Overview of licenses:

      All license text:

      @@ -1711,6 +1712,237 @@

      Used by:

      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. + + +
    1. +

      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 [yyyy] [name of copyright owner]
      +
      +   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.
      +
      +
      +--- LLVM Exceptions to the Apache 2.0 License ----
      +
      +As an exception, if, as a result of your compiling your source code, portions
      +of this Software are embedded into an Object form of such source code, you
      +may redistribute such embedded portions in such Object form without complying
      +with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
      +
      +In addition, if you combine or link compiled forms of this Software with
      +software that is licensed under the GPLv2 ("Combined Software") and if a
      +court of competent jurisdiction determines that the patent provision (Section
      +3), the indemnity provision (Section 9) or other Section of the License
      +conflicts with the conditions of the GPLv2, you may retroactively and
      +prospectively choose to deem waived or otherwise exclude such Section(s) of
      +the License, but only in their entirety and only with respect to the Combined
      +Software.
      +
       
    2. @@ -8233,6 +8465,7 @@

      Used by:

    3. git2
    4. hashbrown
    5. hashbrown
    6. +
    7. hashbrown
    8. hdrhistogram
    9. heck
    10. heck
    11. @@ -9381,6 +9614,201 @@

      Used by:

      of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS + + +
    12. +

      Apache License 2.0

      +

      Used by:

      + +
                                    Apache License
      +                        Version 2.0, January 2004
      +                     https://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.
       
    13. @@ -10860,6 +11288,7 @@

      Apache License 2.0

      Used by:

      ../../LICENSE-APACHE
      @@ -11511,7 +11940,6 @@

      Used by:

      Apache License 2.0

      Used by:

        -
      • apollo-parser
      • async-graphql-axum
      • async-graphql-derive
      • async-graphql-parser
      • @@ -11530,7 +11958,6 @@

        Used by:

      • md5
      • num-cmp
      • prost
      • -
      • rand_core
      • rhai_codegen
      • siphasher
      • system-configuration
      • @@ -12267,6 +12694,9 @@

        Elastic License 2.0

        Used by:

        Copyright 2021 Apollo Graph, Inc.
         
        @@ -16518,6 +16948,32 @@ 

        Used by:

        Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder.
        +
      • +

        zlib License

        +

        Used by:

        + +
        Copyright (c) 2024 Orson Peters
        +
        +This software is provided 'as-is', without any express or implied warranty. In
        +no event will the authors be held liable for any damages arising from the use of
        +this software.
        +
        +Permission is granted to anyone to use this software for any purpose, including
        +commercial applications, and to alter it and redistribute it freely, subject to
        +the following restrictions:
        +
        +1. The origin of this software must not be misrepresented; you must not claim
        +    that you wrote the original software. If you use this software in a product,
        +    an acknowledgment in the product documentation would be appreciated but is
        +    not required.
        +
        +2. Altered source versions must be plainly marked as such, and must not be
        +    misrepresented as being the original software.
        +
        +3. This notice may not be removed or altered from any source distribution.
        +
      diff --git a/scripts/install.sh b/scripts/install.sh index a542864a9a..95b4f39944 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.57.1" +PACKAGE_VERSION="v1.58.0-rc.0" download_binary() { downloader --check From 26fe27b73863493858816695bad1c818f49a3fd9 Mon Sep 17 00:00:00 2001 From: Iryna Shestak Date: Wed, 20 Nov 2024 18:51:34 +0100 Subject: [PATCH 56/77] add `Serialize` to apollo_federation::QueryPlannerConfig (#6295) apollo_federation::QueryPlannerConfig is currently missing Serialize implementation that will be eventually needed for the query planner cache once we use only one planner in the Router. --- apollo-federation/src/query_plan/query_planner.rs | 7 ++++--- apollo-router/src/query_planner/caching_query_planner.rs | 2 -- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/apollo-federation/src/query_plan/query_planner.rs b/apollo-federation/src/query_plan/query_planner.rs index f6f4062760..baa9771dfa 100644 --- a/apollo-federation/src/query_plan/query_planner.rs +++ b/apollo-federation/src/query_plan/query_planner.rs @@ -54,7 +54,7 @@ use crate::Supergraph; pub(crate) const CONTEXT_DIRECTIVE: &str = "context"; -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Clone, Hash, Serialize)] pub struct QueryPlannerConfig { /// Whether the query planner should try to reuse the named fragments of the planned query in /// subgraph fetches. @@ -117,7 +117,7 @@ impl Default for QueryPlannerConfig { } } -#[derive(Debug, Clone, Default, Hash)] +#[derive(Debug, Clone, Default, Hash, Serialize)] pub struct QueryPlanIncrementalDeliveryConfig { /// Enables `@defer` support in the query planner, breaking up the query plan with [DeferNode]s /// as appropriate. @@ -128,10 +128,11 @@ pub struct QueryPlanIncrementalDeliveryConfig { /// Defaults to false. /// /// [DeferNode]: crate::query_plan::DeferNode + #[serde(default)] pub enable_defer: bool, } -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Clone, Hash, Serialize)] pub struct QueryPlannerDebugConfig { /// If used and the supergraph is built from a single subgraph, then user queries do not go /// through the normal query planning and instead a fetch to the one subgraph is built directly diff --git a/apollo-router/src/query_planner/caching_query_planner.rs b/apollo-router/src/query_planner/caching_query_planner.rs index ee5db8dccb..209adcc856 100644 --- a/apollo-router/src/query_planner/caching_query_planner.rs +++ b/apollo-router/src/query_planner/caching_query_planner.rs @@ -56,8 +56,6 @@ pub(crate) const APOLLO_OPERATION_ID: &str = "apollo_operation_id"; #[derive(Debug, Clone, Hash)] pub(crate) enum ConfigMode { - //FIXME: add the Rust planner structure once it is hashable and serializable, - // for now use the JS config as it expected to be identical to the Rust one Rust(Arc), Both(Arc), BothBestEffort(Arc), From 800bf7a2904452e5a815ceccb8d12d23acfc8811 Mon Sep 17 00:00:00 2001 From: Taylor Ninesling Date: Wed, 20 Nov 2024 10:28:07 -0800 Subject: [PATCH 57/77] Ensure that demand control scoring handles custom scalars that represent non-GraphQL-compliant JSON (#6288) --- ...nesling_demand_control_variable_scoring.md | 39 ++++++++ apollo-router/src/json_ext.rs | 34 ------- .../fixtures/arbitrary_json_schema.graphql | 94 +++++++++++++++++++ .../cost_calculator/static_cost.rs | 85 ++++++++++++++++- 4 files changed, 214 insertions(+), 38 deletions(-) create mode 100644 .changesets/fix_tninesling_demand_control_variable_scoring.md create mode 100644 apollo-router/src/plugins/demand_control/cost_calculator/fixtures/arbitrary_json_schema.graphql diff --git a/.changesets/fix_tninesling_demand_control_variable_scoring.md b/.changesets/fix_tninesling_demand_control_variable_scoring.md new file mode 100644 index 0000000000..6ec6b35e22 --- /dev/null +++ b/.changesets/fix_tninesling_demand_control_variable_scoring.md @@ -0,0 +1,39 @@ +### Fix demand control panic for custom scalars that represent non-GraphQL-compliant JSON ([PR #6288](https://github.com/apollographql/router/pull/6288)) + +This panic could be triggered with the following schema: + +``` +scalar ArbitraryJson + +type MyInput { + json: ArbitraryJson +} + +type Query { + fetch(args: MyInput): Int +} +``` + +Then, submitting the query + +``` +query FetchData($myJsonValue: ArbitraryJson) { + fetch(args: { + json: $myJsonValue + }) +} +``` + +and variables + +``` +{ + "myJsonValue": { + "field.with.dots": 1 + } +} +``` + +During scoring, the demand control plugin would attempt to convert the variable structure into a GraphQL-compliant structure requiring valid GraphQL names as keys, but the dot characters in the keys would cause a panic. With this fix, only the GraphQL compliant part of the input object is scored, and the arbitrary JSON marked by the custom scalar is scored as an opaque scalar, similar to how we process built-ins like `Int` or `String`. + +By [@tninesling](https://github.com/tninesling) in https://github.com/apollographql/router/pull/6288 diff --git a/apollo-router/src/json_ext.rs b/apollo-router/src/json_ext.rs index 9bc94833d0..81423deb8b 100644 --- a/apollo-router/src/json_ext.rs +++ b/apollo-router/src/json_ext.rs @@ -155,9 +155,6 @@ pub(crate) trait ValueExt { /// value type fn json_type_name(&self) -> &'static str; - /// Convert this value to an instance of `apollo_compiler::ast::Value` - fn to_ast(&self) -> apollo_compiler::ast::Value; - fn as_i32(&self) -> Option; } @@ -542,37 +539,6 @@ impl ValueExt for Value { } } - fn to_ast(&self) -> apollo_compiler::ast::Value { - match self { - Value::Null => apollo_compiler::ast::Value::Null, - Value::Bool(b) => apollo_compiler::ast::Value::Boolean(*b), - Value::Number(n) if n.is_f64() => { - apollo_compiler::ast::Value::Float(n.as_f64().expect("is float").into()) - } - Value::Number(n) => { - apollo_compiler::ast::Value::Int((n.as_i64().expect("is int") as i32).into()) - } - Value::String(s) => apollo_compiler::ast::Value::String(s.as_str().to_string()), - Value::Array(inner_vars) => apollo_compiler::ast::Value::List( - inner_vars - .iter() - .map(|v| apollo_compiler::Node::new(v.to_ast())) - .collect(), - ), - Value::Object(inner_vars) => apollo_compiler::ast::Value::Object( - inner_vars - .iter() - .map(|(k, v)| { - ( - apollo_compiler::Name::new(k.as_str()).expect("is valid name"), - apollo_compiler::Node::new(v.to_ast()), - ) - }) - .collect(), - ), - } - } - fn as_i32(&self) -> Option { self.as_i64()?.to_i32() } diff --git a/apollo-router/src/plugins/demand_control/cost_calculator/fixtures/arbitrary_json_schema.graphql b/apollo-router/src/plugins/demand_control/cost_calculator/fixtures/arbitrary_json_schema.graphql new file mode 100644 index 0000000000..2b4d7565f3 --- /dev/null +++ b/apollo-router/src/plugins/demand_control/cost_calculator/fixtures/arbitrary_json_schema.graphql @@ -0,0 +1,94 @@ +schema + @link(url: "https://specs.apollo.dev/link/v1.0") + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { + query: Query +} + +directive @join__directive( + graphs: [join__Graph!] + name: String! + args: join__DirectiveArguments +) repeatable on SCHEMA | OBJECT | INTERFACE | FIELD_DEFINITION + +directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE + +directive @join__field( + graph: join__Graph + requires: join__FieldSet + provides: join__FieldSet + type: String + external: Boolean + override: String + usedOverridden: Boolean + overrideLabel: String + contextArguments: [join__ContextArgument!] +) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + +directive @join__graph(name: String!, url: String!) on ENUM_VALUE + +directive @join__implements( + graph: join__Graph! + interface: String! +) repeatable on OBJECT | INTERFACE + +directive @join__type( + graph: join__Graph! + key: join__FieldSet + extension: Boolean! = false + resolvable: Boolean! = true + isInterfaceObject: Boolean! = false +) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + +directive @join__unionMember( + graph: join__Graph! + member: String! +) repeatable on UNION + +directive @link( + url: String + as: String + for: link__Purpose + import: [link__Import] +) repeatable on SCHEMA + +scalar ArbitraryJson @join__type(graph: SUBGRAPHWITHCUSTOMSCALAR) + +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + +scalar join__DirectiveArguments + +scalar join__FieldSet + +scalar join__FieldValue + +enum join__Graph { + SUBGRAPHWITHCUSTOMSCALAR + @join__graph(name: "subgraphWithCustomScalar", url: "http://localhost:4001") +} + +scalar link__Import + +enum link__Purpose { + """ + `SECURITY` features provide metadata necessary to securely resolve fields. + """ + SECURITY + + """ + `EXECUTION` features provide metadata necessary for operation execution. + """ + EXECUTION +} + +input MyInput @join__type(graph: SUBGRAPHWITHCUSTOMSCALAR) { + json: ArbitraryJson +} + +type Query @join__type(graph: SUBGRAPHWITHCUSTOMSCALAR) { + fetch(args: MyInput): String +} diff --git a/apollo-router/src/plugins/demand_control/cost_calculator/static_cost.rs b/apollo-router/src/plugins/demand_control/cost_calculator/static_cost.rs index 3c0d973ebb..397f33e9b6 100644 --- a/apollo-router/src/plugins/demand_control/cost_calculator/static_cost.rs +++ b/apollo-router/src/plugins/demand_control/cost_calculator/static_cost.rs @@ -22,7 +22,6 @@ use super::DemandControlError; use crate::graphql::Response; use crate::graphql::ResponseVisitor; use crate::json_ext::Object; -use crate::json_ext::ValueExt; use crate::plugins::demand_control::cost_calculator::directives::CostDirective; use crate::plugins::demand_control::cost_calculator::directives::ListSizeDirective; use crate::query_planner::fetch::SubgraphOperation; @@ -50,8 +49,6 @@ fn score_argument( schema: &DemandControlledSchema, variables: &Object, ) -> Result { - let cost_directive = - CostDirective::from_argument(schema.directive_name_map(), argument_definition); let ty = schema .types .get(argument_definition.ty.inner_named_type()) @@ -62,6 +59,9 @@ fn score_argument( argument_definition.ty.inner_named_type() )) })?; + let cost_directive = + CostDirective::from_argument(schema.directive_name_map(), argument_definition) + .or(CostDirective::from_type(schema.directive_name_map(), ty)); match (argument, ty) { (_, ExtendedType::Interface(_)) @@ -99,7 +99,7 @@ fn score_argument( // We make a best effort attempt to score the variable, but some of these may not exist in the variables // sent on the supergraph request, such as `$representations`. if let Some(variable) = variables.get(name.as_str()) { - score_argument(&variable.to_ast(), argument_definition, schema, variables) + score_variable(variable, argument_definition, schema) } else { Ok(0.0) } @@ -109,6 +109,62 @@ fn score_argument( } } +fn score_variable( + variable: &Value, + argument_definition: &Node, + schema: &DemandControlledSchema, +) -> Result { + let ty = schema + .types + .get(argument_definition.ty.inner_named_type()) + .ok_or_else(|| { + DemandControlError::QueryParseFailure(format!( + "Argument {} was found in query, but its type ({}) was not found in the schema", + argument_definition.name, + argument_definition.ty.inner_named_type() + )) + })?; + let cost_directive = + CostDirective::from_argument(schema.directive_name_map(), argument_definition) + .or(CostDirective::from_type(schema.directive_name_map(), ty)); + + match (variable, ty) { + (_, ExtendedType::Interface(_)) + | (_, ExtendedType::Object(_)) + | (_, ExtendedType::Union(_)) => Err(DemandControlError::QueryParseFailure( + format!( + "Argument {} has type {}, but objects, interfaces, and unions are disallowed in this position", + argument_definition.name, + argument_definition.ty.inner_named_type() + ) + )), + + (Value::Object(inner_args), ExtendedType::InputObject(inner_arg_defs)) => { + let mut cost = cost_directive.map_or(1.0, |cost| cost.weight()); + for (arg_name, arg_val) in inner_args { + let arg_def = inner_arg_defs.fields.get(arg_name.as_str()).ok_or_else(|| { + DemandControlError::QueryParseFailure(format!( + "Argument {} was found in query, but its type ({}) was not found in the schema", + argument_definition.name, + argument_definition.ty.inner_named_type() + )) + })?; + cost += score_variable(arg_val, arg_def, schema)?; + } + Ok(cost) + } + (Value::Array(inner_args), _) => { + let mut cost = cost_directive.map_or(0.0, |cost| cost.weight()); + for arg_val in inner_args { + cost += score_variable(arg_val, argument_definition, schema)?; + } + Ok(cost) + } + (Value::Null, _) => Ok(0.0), + _ => Ok(cost_directive.map_or(0.0, |cost| cost.weight())) + } +} + impl StaticCostCalculator { pub(crate) fn new( supergraph_schema: Arc, @@ -1073,4 +1129,25 @@ mod tests { assert_eq!(planned_cost_rust(schema, query, variables), 127.0); assert_eq!(actual_cost(schema, query, variables, response), 125.0); } + + #[test] + fn arbitrary_json_as_custom_scalar_in_variables() { + let schema = include_str!("./fixtures/arbitrary_json_schema.graphql"); + let query = r#" + query FetchData($myJsonValue: ArbitraryJson) { + fetch(args: { + json: $myJsonValue + }) + } + "#; + let variables = r#" + { + "myJsonValue": { + "field.with.dots": 1 + } + } + "#; + + assert_eq!(estimated_cost(schema, query, variables), 1.0); + } } From 165bd9257da094a4c831511ee72afceb3d39af51 Mon Sep 17 00:00:00 2001 From: Chris Lenfest Date: Thu, 21 Nov 2024 08:14:23 -0600 Subject: [PATCH 58/77] feat(federation): add `@context` support (#6310) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR enables [`@context`](https://www.apollographql.com/docs/graphos/reference/federation/directives#context) and [`@fromContext`](https://www.apollographql.com/docs/graphos/reference/federation/directives#fromcontext) directive support in the rust query planner. As a result, those graphs using either of these directives will no longer fall back to the legacy (js) query planner when in `experimental_query_planner_mode: both_best_effort`. Co-authored-by: Iryna Shestak Co-authored-by: Taylor Ninesling Co-authored-by: TylerBloom Co-authored-by: Sachin D. Shinde Co-authored-by: Renรฉe Kooi --- .../feat_router_528_impl_set_context.md | 6 + ...nesling_demand_control_variable_scoring.md | 39 + Cargo.lock | 23 +- apollo-federation/Cargo.toml | 1 + apollo-federation/src/error/mod.rs | 2 +- apollo-federation/src/link/argument.rs | 18 + .../src/link/context_spec_definition.rs | 62 + .../src/link/federation_spec_definition.rs | 117 ++ .../src/link/join_spec_definition.rs | 89 + apollo-federation/src/link/mod.rs | 1 + apollo-federation/src/link/spec.rs | 7 + apollo-federation/src/operation/mod.rs | 5 +- apollo-federation/src/operation/rebase.rs | 46 +- .../src/query_graph/build_query_graph.rs | 331 +++- .../src/query_graph/condition_resolver.rs | 32 +- .../src/query_graph/graph_path.rs | 529 +++++- apollo-federation/src/query_graph/mod.rs | 38 + .../src/query_graph/path_tree.rs | 78 +- apollo-federation/src/query_plan/display.rs | 1 + .../src/query_plan/fetch_dependency_graph.rs | 892 +++++++--- apollo-federation/src/query_plan/mod.rs | 13 +- .../src/query_plan/query_planner.rs | 47 +- .../query_plan/query_planning_traversal.rs | 35 +- apollo-federation/src/schema/position.rs | 2 +- apollo-federation/src/subgraph/spec.rs | 62 +- apollo-federation/src/supergraph/mod.rs | 217 ++- apollo-federation/src/supergraph/schema.rs | 4 + .../src/utils/fallible_iterator.rs | 22 + apollo-federation/tests/extract_subgraphs.rs | 108 ++ .../query_plan/build_query_plan_tests.rs | 1 + .../build_query_plan_tests/context.rs | 1491 +++++++++++++++++ .../set_context_one_subgraph.graphql | 87 + ...g_back_and_forth_between_subgraphs.graphql | 110 ++ ...cesses_a_different_top_level_query.graphql | 87 + ...t_before_key_resolution_transition.graphql | 95 ++ ...est_efficiently_merge_fetch_groups.graphql | 120 ++ ...set_context_test_fetched_as_a_list.graphql | 88 + ...ext_test_impacts_on_query_planning.graphql | 106 ++ ...et_context_test_variable_is_a_list.graphql | 87 + ...already_in_a_different_fetch_group.graphql | 88 + ...ariable_is_from_different_subgraph.graphql | 88 + ...est_variable_is_from_same_subgraph.graphql | 88 + ...est_with_type_conditions_for_union.graphql | 102 ++ ...tract_subgraphs__can_extract_subgraph.snap | 8 + ...mand_control_directive_name_conflicts.snap | 8 + ...mand_control_directive_name_conflicts.snap | 8 + ...s__extracts_demand_control_directives.snap | 8 + ...cts_renamed_demand_control_directives.snap | 8 + ...aphs__extracts_set_context_directives.snap | 170 ++ apollo-router/src/json_ext.rs | 34 - .../fixtures/arbitrary_json_schema.graphql | 94 ++ .../cost_calculator/static_cost.rs | 85 +- .../query_planner/caching_query_planner.rs | 2 - apollo-router/src/query_planner/convert.rs | 1 + .../testdata/supergraph_with_context.graphql | 2 +- .../set_context/one_fetch_failure.json | 23 + .../fixtures/set_context/one_null_param.json | 20 + .../tests/integration/query_planner.rs | 74 - apollo-router/tests/set_context.rs | 293 +++- ...ntext_dependent_fetch_failure_rust_qp.snap | 115 ++ ...xt__set_context_list_of_lists_rust_qp.snap | 112 ++ ...set_context__set_context_list_rust_qp.snap | 107 ++ ...ext__set_context_no_typenames_rust_qp.snap | 98 ++ .../set_context__set_context_rust_qp.snap | 100 ++ ...xt__set_context_type_mismatch_rust_qp.snap | 98 ++ ...et_context__set_context_union_rust_qp.snap | 173 ++ ...ntext_unrelated_fetch_failure_rust_qp.snap | 171 ++ ...ontext__set_context_with_null_rust_qp.snap | 98 ++ 68 files changed, 6894 insertions(+), 481 deletions(-) create mode 100644 .changesets/feat_router_528_impl_set_context.md create mode 100644 .changesets/fix_tninesling_demand_control_variable_scoring.md create mode 100644 apollo-federation/src/link/context_spec_definition.rs create mode 100644 apollo-federation/tests/query_plan/build_query_plan_tests/context.rs create mode 100644 apollo-federation/tests/query_plan/supergraphs/set_context_one_subgraph.graphql create mode 100644 apollo-federation/tests/query_plan/supergraphs/set_context_required_field_is_several_levels_deep_going_back_and_forth_between_subgraphs.graphql create mode 100644 apollo-federation/tests/query_plan/supergraphs/set_context_test_accesses_a_different_top_level_query.graphql create mode 100644 apollo-federation/tests/query_plan/supergraphs/set_context_test_before_key_resolution_transition.graphql create mode 100644 apollo-federation/tests/query_plan/supergraphs/set_context_test_efficiently_merge_fetch_groups.graphql create mode 100644 apollo-federation/tests/query_plan/supergraphs/set_context_test_fetched_as_a_list.graphql create mode 100644 apollo-federation/tests/query_plan/supergraphs/set_context_test_impacts_on_query_planning.graphql create mode 100644 apollo-federation/tests/query_plan/supergraphs/set_context_test_variable_is_a_list.graphql create mode 100644 apollo-federation/tests/query_plan/supergraphs/set_context_test_variable_is_already_in_a_different_fetch_group.graphql create mode 100644 apollo-federation/tests/query_plan/supergraphs/set_context_test_variable_is_from_different_subgraph.graphql create mode 100644 apollo-federation/tests/query_plan/supergraphs/set_context_test_variable_is_from_same_subgraph.graphql create mode 100644 apollo-federation/tests/query_plan/supergraphs/set_context_test_with_type_conditions_for_union.graphql create mode 100644 apollo-federation/tests/snapshots/main__extract_subgraphs__extracts_set_context_directives.snap create mode 100644 apollo-router/src/plugins/demand_control/cost_calculator/fixtures/arbitrary_json_schema.graphql create mode 100644 apollo-router/tests/snapshots/set_context__set_context_dependent_fetch_failure_rust_qp.snap create mode 100644 apollo-router/tests/snapshots/set_context__set_context_list_of_lists_rust_qp.snap create mode 100644 apollo-router/tests/snapshots/set_context__set_context_list_rust_qp.snap create mode 100644 apollo-router/tests/snapshots/set_context__set_context_no_typenames_rust_qp.snap create mode 100644 apollo-router/tests/snapshots/set_context__set_context_rust_qp.snap create mode 100644 apollo-router/tests/snapshots/set_context__set_context_type_mismatch_rust_qp.snap create mode 100644 apollo-router/tests/snapshots/set_context__set_context_union_rust_qp.snap create mode 100644 apollo-router/tests/snapshots/set_context__set_context_unrelated_fetch_failure_rust_qp.snap create mode 100644 apollo-router/tests/snapshots/set_context__set_context_with_null_rust_qp.snap diff --git a/.changesets/feat_router_528_impl_set_context.md b/.changesets/feat_router_528_impl_set_context.md new file mode 100644 index 0000000000..f47bb8ac23 --- /dev/null +++ b/.changesets/feat_router_528_impl_set_context.md @@ -0,0 +1,6 @@ +### Add `@context` support in the Native Query Planner ([PR #6310](https://github.com/apollographql/router/pull/6310)) + +The [`@context`](https://www.apollographql.com/docs/graphos/reference/federation/directives#context) feature is now available in the native query planner. +This brings the native query planner to feature parity with the legacy query planner for all Federation v2 graphs. + +By [@clenfest](https://github.com/clenfest), [@TylerBloom](https://github.com/TylerBloom) in https://github.com/apollographql/router/pull/6310 \ No newline at end of file diff --git a/.changesets/fix_tninesling_demand_control_variable_scoring.md b/.changesets/fix_tninesling_demand_control_variable_scoring.md new file mode 100644 index 0000000000..6ec6b35e22 --- /dev/null +++ b/.changesets/fix_tninesling_demand_control_variable_scoring.md @@ -0,0 +1,39 @@ +### Fix demand control panic for custom scalars that represent non-GraphQL-compliant JSON ([PR #6288](https://github.com/apollographql/router/pull/6288)) + +This panic could be triggered with the following schema: + +``` +scalar ArbitraryJson + +type MyInput { + json: ArbitraryJson +} + +type Query { + fetch(args: MyInput): Int +} +``` + +Then, submitting the query + +``` +query FetchData($myJsonValue: ArbitraryJson) { + fetch(args: { + json: $myJsonValue + }) +} +``` + +and variables + +``` +{ + "myJsonValue": { + "field.with.dots": 1 + } +} +``` + +During scoring, the demand control plugin would attempt to convert the variable structure into a GraphQL-compliant structure requiring valid GraphQL names as keys, but the dot characters in the keys would cause a panic. With this fix, only the GraphQL compliant part of the input object is scored, and the arbitrary JSON marked by the custom scalar is scored as an opaque scalar, similar to how we process built-ins like `Int` or `String`. + +By [@tninesling](https://github.com/tninesling) in https://github.com/apollographql/router/pull/6288 diff --git a/Cargo.lock b/Cargo.lock index 8428ccc8a5..9fde13394b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -192,6 +192,7 @@ dependencies = [ "multimap 0.10.0", "nom", "petgraph", + "regex", "ron", "serde", "serde_json_bytes", @@ -2934,8 +2935,8 @@ dependencies = [ "aho-corasick", "bstr", "log", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", + "regex-automata 0.4.8", + "regex-syntax 0.8.5", ] [[package]] @@ -5306,14 +5307,14 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.5" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", + "regex-automata 0.4.8", + "regex-syntax 0.8.5", ] [[package]] @@ -5327,13 +5328,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.4", + "regex-syntax 0.8.5", ] [[package]] @@ -5350,9 +5351,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" diff --git a/apollo-federation/Cargo.toml b/apollo-federation/Cargo.toml index 261f5cea22..7f5d39efc7 100644 --- a/apollo-federation/Cargo.toml +++ b/apollo-federation/Cargo.toml @@ -38,6 +38,7 @@ url = "2" tracing = "0.1.40" ron = { version = "0.8.1", optional = true } either = "1.13.0" +regex = "1.11.1" [dev-dependencies] hex.workspace = true diff --git a/apollo-federation/src/error/mod.rs b/apollo-federation/src/error/mod.rs index cd163ecdab..8d1ceb156b 100644 --- a/apollo-federation/src/error/mod.rs +++ b/apollo-federation/src/error/mod.rs @@ -50,7 +50,7 @@ macro_rules! internal_error { #[macro_export] macro_rules! bail { ( $( $arg:tt )+ ) => { - return Err($crate::internal_error!( $( $arg )+ ).into()); + return Err($crate::internal_error!( $( $arg )+ ).into()) } } diff --git a/apollo-federation/src/link/argument.rs b/apollo-federation/src/link/argument.rs index 12702dadb2..aeac4ccd0e 100644 --- a/apollo-federation/src/link/argument.rs +++ b/apollo-federation/src/link/argument.rs @@ -5,6 +5,7 @@ use apollo_compiler::schema::Directive; use apollo_compiler::Name; use apollo_compiler::Node; +use crate::bail; use crate::error::FederationError; use crate::error::SingleFederationError; use crate::link::graphql_definition::BooleanOrVariable; @@ -132,3 +133,20 @@ pub(crate) fn directive_optional_variable_boolean_argument( None => Ok(None), } } + +pub(crate) fn directive_optional_list_argument<'a>( + application: &'a Node, + name: &'_ Name, +) -> Result]>, FederationError> { + match application.specified_argument_by_name(name) { + None => Ok(None), + Some(value) => match value.as_ref() { + Value::Null => Ok(None), + Value::List(values) => Ok(Some(values.as_slice())), + _ => bail!( + r#"Argument "{name}" of directive "@{}" must be a boolean."#, + application.name + ), + }, + } +} diff --git a/apollo-federation/src/link/context_spec_definition.rs b/apollo-federation/src/link/context_spec_definition.rs new file mode 100644 index 0000000000..ff4217c2d6 --- /dev/null +++ b/apollo-federation/src/link/context_spec_definition.rs @@ -0,0 +1,62 @@ +use apollo_compiler::name; +use apollo_compiler::Name; +use lazy_static::lazy_static; + +use crate::error::FederationError; +use crate::link::spec::Identity; +use crate::link::spec::Url; +use crate::link::spec::Version; +use crate::link::spec_definition::SpecDefinition; +use crate::link::spec_definition::SpecDefinitions; +use crate::schema::FederationSchema; + +pub(crate) const CONTEXT_DIRECTIVE_NAME_IN_SPEC: Name = name!("context"); +pub(crate) const CONTEXT_DIRECTIVE_NAME_DEFAULT: Name = name!("federation__context"); + +#[derive(Clone)] +pub(crate) struct ContextSpecDefinition { + url: Url, + minimum_federation_version: Option, +} + +impl ContextSpecDefinition { + pub(crate) fn new(version: Version, minimum_federation_version: Option) -> Self { + Self { + url: Url { + identity: Identity::context_identity(), + version, + }, + minimum_federation_version, + } + } + + pub(crate) fn context_directive_name_in_schema( + &self, + schema: &FederationSchema, + ) -> Result { + Ok(self + .directive_name_in_schema(schema, &CONTEXT_DIRECTIVE_NAME_IN_SPEC)? + .unwrap_or(CONTEXT_DIRECTIVE_NAME_DEFAULT)) + } +} + +impl SpecDefinition for ContextSpecDefinition { + fn url(&self) -> &Url { + &self.url + } + + fn minimum_federation_version(&self) -> Option<&Version> { + self.minimum_federation_version.as_ref() + } +} + +lazy_static! { + pub(crate) static ref CONTEXT_VERSIONS: SpecDefinitions = { + let mut definitions = SpecDefinitions::new(Identity::context_identity()); + definitions.add(ContextSpecDefinition::new( + Version { major: 0, minor: 1 }, + Some(Version { major: 2, minor: 8 }), + )); + definitions + }; +} diff --git a/apollo-federation/src/link/federation_spec_definition.rs b/apollo-federation/src/link/federation_spec_definition.rs index 184e93b690..a773d860c7 100644 --- a/apollo-federation/src/link/federation_spec_definition.rs +++ b/apollo-federation/src/link/federation_spec_definition.rs @@ -32,12 +32,16 @@ pub(crate) const FEDERATION_REQUIRES_DIRECTIVE_NAME_IN_SPEC: Name = name!("requi pub(crate) const FEDERATION_PROVIDES_DIRECTIVE_NAME_IN_SPEC: Name = name!("provides"); pub(crate) const FEDERATION_SHAREABLE_DIRECTIVE_NAME_IN_SPEC: Name = name!("shareable"); pub(crate) const FEDERATION_OVERRIDE_DIRECTIVE_NAME_IN_SPEC: Name = name!("override"); +pub(crate) const FEDERATION_CONTEXT_DIRECTIVE_NAME_IN_SPEC: Name = name!("context"); +pub(crate) const FEDERATION_FROM_CONTEXT_DIRECTIVE_NAME_IN_SPEC: Name = name!("fromContext"); pub(crate) const FEDERATION_FIELDS_ARGUMENT_NAME: Name = name!("fields"); pub(crate) const FEDERATION_RESOLVABLE_ARGUMENT_NAME: Name = name!("resolvable"); pub(crate) const FEDERATION_REASON_ARGUMENT_NAME: Name = name!("reason"); pub(crate) const FEDERATION_FROM_ARGUMENT_NAME: Name = name!("from"); pub(crate) const FEDERATION_OVERRIDE_LABEL_ARGUMENT_NAME: Name = name!("label"); +pub(crate) const FEDERATION_NAME_ARGUMENT_NAME: Name = name!("name"); +pub(crate) const FEDERATION_FIELD_ARGUMENT_NAME: Name = name!("field"); pub(crate) struct KeyDirectiveArguments<'doc> { pub(crate) fields: &'doc str, @@ -52,6 +56,14 @@ pub(crate) struct ProvidesDirectiveArguments<'doc> { pub(crate) fields: &'doc str, } +pub(crate) struct ContextDirectiveArguments<'doc> { + pub(crate) name: &'doc str, +} + +pub(crate) struct FromContextDirectiveArguments<'doc> { + pub(crate) field: &'doc str, +} + pub(crate) struct OverrideDirectiveArguments<'doc> { pub(crate) from: &'doc str, pub(crate) label: Option<&'doc str>, @@ -422,6 +434,111 @@ impl FederationSpecDefinition { }) } + pub(crate) fn context_directive_definition<'schema>( + &self, + schema: &'schema FederationSchema, + ) -> Result<&'schema Node, FederationError> { + self.directive_definition(schema, &FEDERATION_CONTEXT_DIRECTIVE_NAME_IN_SPEC)? + .ok_or_else(|| { + FederationError::internal(format!( + "Unexpectedly could not find federation spec's \"@{}\" directive definition", + FEDERATION_CONTEXT_DIRECTIVE_NAME_IN_SPEC, + )) + }) + } + + pub(crate) fn context_directive( + &self, + schema: &FederationSchema, + name: String, + ) -> Result { + let name_in_schema = self + .directive_name_in_schema(schema, &FEDERATION_CONTEXT_DIRECTIVE_NAME_IN_SPEC)? + .ok_or_else(|| SingleFederationError::Internal { + message: "Unexpectedly could not find federation spec in schema".to_owned(), + })?; + + let arguments = vec![Node::new(Argument { + name: FEDERATION_NAME_ARGUMENT_NAME, + value: Node::new(Value::String(name)), + })]; + + Ok(Directive { + name: name_in_schema, + arguments, + }) + } + + pub(crate) fn context_directive_arguments( + application: &Node, + ) -> Result { + Ok(ContextDirectiveArguments { + name: directive_required_string_argument(application, &FEDERATION_NAME_ARGUMENT_NAME)?, + }) + } + + // The directive is named `@fromContex`. This is confusing for clippy, as + // `from` is a conventional prefix used in conversion methods, which do not + // take `self` as an argument. This function does **not** perform + // conversion, but extracts `@fromContext` directive definition. + #[allow(clippy::wrong_self_convention)] + pub(crate) fn from_context_directive_definition<'schema>( + &self, + schema: &'schema FederationSchema, + ) -> Result<&'schema Node, FederationError> { + self.directive_definition(schema, &FEDERATION_FROM_CONTEXT_DIRECTIVE_NAME_IN_SPEC)? + .ok_or_else(|| { + FederationError::internal(format!( + "Unexpectedly could not find federation spec's \"@{}\" directive definition", + FEDERATION_FROM_CONTEXT_DIRECTIVE_NAME_IN_SPEC, + )) + }) + } + + // The directive is named `@fromContex`. This is confusing for clippy, as + // `from` is a conventional prefix used in conversion methods, which do not + // take `self` as an argument. This function does **not** perform + // conversion, but extracts `@fromContext` directive arguments. + #[allow(clippy::wrong_self_convention)] + pub(crate) fn from_context_directive_arguments<'doc>( + &self, + application: &'doc Node, + ) -> Result, FederationError> { + Ok(FromContextDirectiveArguments { + field: directive_required_string_argument( + application, + &FEDERATION_FIELD_ARGUMENT_NAME, + )?, + }) + } + + // The directive is named `@fromContex`. This is confusing for clippy, as + // `from` is a conventional prefix used in conversion methods, which do not + // take `self` as an argument. This function does **not** perform + // conversion, but extracts `@fromContext` directive. + #[allow(clippy::wrong_self_convention)] + pub(crate) fn from_context_directive( + &self, + schema: &FederationSchema, + name: String, + ) -> Result { + let name_in_schema = self + .directive_name_in_schema(schema, &FEDERATION_FROM_CONTEXT_DIRECTIVE_NAME_IN_SPEC)? + .ok_or_else(|| SingleFederationError::Internal { + message: "Unexpectedly could not find federation spec in schema".to_owned(), + })?; + + let arguments = vec![Node::new(Argument { + name: FEDERATION_FIELD_ARGUMENT_NAME, + value: Node::new(Value::String(name)), + })]; + + Ok(Directive { + name: name_in_schema, + arguments, + }) + } + pub(crate) fn get_cost_spec_definition( &self, schema: &FederationSchema, diff --git a/apollo-federation/src/link/join_spec_definition.rs b/apollo-federation/src/link/join_spec_definition.rs index 1328cbdcb7..19124f579a 100644 --- a/apollo-federation/src/link/join_spec_definition.rs +++ b/apollo-federation/src/link/join_spec_definition.rs @@ -1,3 +1,4 @@ +use apollo_compiler::ast::Value; use apollo_compiler::name; use apollo_compiler::schema::Directive; use apollo_compiler::schema::DirectiveDefinition; @@ -5,8 +6,11 @@ use apollo_compiler::schema::EnumType; use apollo_compiler::schema::ExtendedType; use apollo_compiler::Name; use apollo_compiler::Node; +use itertools::Itertools; use lazy_static::lazy_static; +use super::argument::directive_optional_list_argument; +use crate::bail; use crate::error::FederationError; use crate::error::SingleFederationError; use crate::link::argument::directive_optional_boolean_argument; @@ -45,6 +49,7 @@ pub(crate) const JOIN_OVERRIDE_LABEL_ARGUMENT_NAME: Name = name!("overrideLabel" pub(crate) const JOIN_USEROVERRIDDEN_ARGUMENT_NAME: Name = name!("usedOverridden"); pub(crate) const JOIN_INTERFACE_ARGUMENT_NAME: Name = name!("interface"); pub(crate) const JOIN_MEMBER_ARGUMENT_NAME: Name = name!("member"); +pub(crate) const JOIN_MEMBER_CONTEXT_ARGUMENTS: Name = name!("contextArguments"); pub(crate) struct GraphDirectiveArguments<'doc> { pub(crate) name: &'doc str, @@ -59,6 +64,78 @@ pub(crate) struct TypeDirectiveArguments<'doc> { pub(crate) is_interface_object: bool, } +pub(crate) struct ContextArgument<'doc> { + pub(crate) name: &'doc str, + pub(crate) type_: &'doc str, + pub(crate) context: &'doc str, + pub(crate) selection: &'doc str, +} + +impl<'doc> TryFrom<&'doc Value> for ContextArgument<'doc> { + type Error = FederationError; + + fn try_from(value: &'doc Value) -> Result { + fn insert_value<'a>( + name: &str, + field: &mut Option<&'a Value>, + value: &'a Value, + ) -> Result<(), FederationError> { + if let Some(first_value) = field { + bail!("Duplicate contextArgument for '{name}' field: {first_value} and {value}") + } + let _ = field.insert(value); + Ok(()) + } + + fn field_or_else<'a>( + field_name: &'static str, + field: Option<&'a Value>, + ) -> Result<&'a str, FederationError> { + field + .ok_or_else(|| { + FederationError::internal(format!( + "'{field_name}' field was missing from contextArgument" + )) + })? + .as_str() + .ok_or_else(|| { + FederationError::internal(format!( + "'{field_name}' field of contextArgument was not a string" + )) + }) + } + + let Value::Object(names) = value else { + bail!("Item in contextArgument list is not an object {value}") + }; + let mut name = None; + let mut type_ = None; + let mut context = None; + let mut selection = None; + for (arg_name, value) in names.as_slice() { + match arg_name.as_str() { + "name" => insert_value(arg_name, &mut name, value)?, + "type" => insert_value(arg_name, &mut type_, value)?, + "context" => insert_value(arg_name, &mut context, value)?, + "selection" => insert_value(arg_name, &mut selection, value)?, + _ => bail!("Found unknown contextArgument {arg_name}"), + } + } + + let name = field_or_else("name", name)?; + let type_ = field_or_else("type_", type_)?; + let context = field_or_else("context", context)?; + let selection = field_or_else("selection", selection)?; + + Ok(Self { + name, + type_, + context, + selection, + }) + } +} + pub(crate) struct FieldDirectiveArguments<'doc> { pub(crate) graph: Option, pub(crate) requires: Option<&'doc str>, @@ -68,6 +145,7 @@ pub(crate) struct FieldDirectiveArguments<'doc> { pub(crate) override_: Option<&'doc str>, pub(crate) override_label: Option<&'doc str>, pub(crate) user_overridden: Option, + pub(crate) context_arguments: Option>>, } pub(crate) struct ImplementsDirectiveArguments<'doc> { @@ -228,6 +306,17 @@ impl JoinSpecDefinition { application, &JOIN_USEROVERRIDDEN_ARGUMENT_NAME, )?, + context_arguments: directive_optional_list_argument( + application, + &JOIN_MEMBER_CONTEXT_ARGUMENTS, + )? + .map(|values| { + values + .iter() + .map(|value| ContextArgument::try_from(value.as_ref())) + .try_collect() + }) + .transpose()?, }) } diff --git a/apollo-federation/src/link/mod.rs b/apollo-federation/src/link/mod.rs index 76a59da2ea..39f51e9499 100644 --- a/apollo-federation/src/link/mod.rs +++ b/apollo-federation/src/link/mod.rs @@ -22,6 +22,7 @@ use crate::link::spec::Identity; use crate::link::spec::Url; pub(crate) mod argument; +pub(crate) mod context_spec_definition; pub(crate) mod cost_spec_definition; pub mod database; pub(crate) mod federation_spec_definition; diff --git a/apollo-federation/src/link/spec.rs b/apollo-federation/src/link/spec.rs index 5c1386644b..78fe3f33e9 100644 --- a/apollo-federation/src/link/spec.rs +++ b/apollo-federation/src/link/spec.rs @@ -95,6 +95,13 @@ impl Identity { name: name!("cost"), } } + + pub fn context_identity() -> Identity { + Identity { + domain: APOLLO_SPEC_DOMAIN.to_string(), + name: name!("context"), + } + } } /// The version of a `@link` specification, in the form of a major and minor version numbers. diff --git a/apollo-federation/src/operation/mod.rs b/apollo-federation/src/operation/mod.rs index 5c0dc7c71f..1fe1f16287 100644 --- a/apollo-federation/src/operation/mod.rs +++ b/apollo-federation/src/operation/mod.rs @@ -20,7 +20,6 @@ use std::ops::Deref; use std::sync::atomic; use std::sync::Arc; -use apollo_compiler::collections::HashSet; use apollo_compiler::collections::IndexMap; use apollo_compiler::collections::IndexSet; use apollo_compiler::executable; @@ -2982,7 +2981,7 @@ pub(crate) struct NormalizedDefer { } struct DeferNormalizer { - used_labels: HashSet, + used_labels: IndexSet, assigned_labels: IndexSet, conditions: IndexMap>, label_offset: usize, @@ -2991,7 +2990,7 @@ struct DeferNormalizer { impl DeferNormalizer { fn new(selection_set: &SelectionSet) -> Result { let mut digest = Self { - used_labels: HashSet::default(), + used_labels: IndexSet::default(), label_offset: 0, assigned_labels: IndexSet::default(), conditions: IndexMap::default(), diff --git a/apollo-federation/src/operation/rebase.rs b/apollo-federation/src/operation/rebase.rs index ffc16d1b01..09b8799067 100644 --- a/apollo-federation/src/operation/rebase.rs +++ b/apollo-federation/src/operation/rebase.rs @@ -22,6 +22,7 @@ use super::SelectionSet; use super::TYPENAME_FIELD; use crate::ensure; use crate::error::FederationError; +use crate::link::federation_spec_definition::get_federation_spec_definition_from_subgraph; use crate::schema::position::CompositeTypeDefinitionPosition; use crate::schema::position::OutputTypeDefinitionPosition; use crate::schema::ValidFederationSchema; @@ -265,19 +266,42 @@ impl Field { }; return Ok(Some(schema.get_type(type_name.clone())?.try_into()?)); } - if self.can_rebase_on(parent_type)? { - let Some(type_name) = parent_type - .field(data.field_position.field_name().clone()) - .ok() - .and_then(|field_pos| field_pos.get(schema.schema()).ok()) - .map(|field| field.ty.inner_named_type()) - else { + if !self.can_rebase_on(parent_type)? { + return Ok(None); + } + let Some(field_definition) = parent_type + .field(data.field_position.field_name().clone()) + .ok() + .and_then(|field_pos| field_pos.get(schema.schema()).ok()) + else { + return Ok(None); + }; + if let Ok(federation_spec_definition) = get_federation_spec_definition_from_subgraph(schema) + { + let from_context_directive_definition_name = &federation_spec_definition + .from_context_directive_definition(schema)? + .name; + // We need to prevent arguments with `@fromContext` from being lost/overwriten. If the + // would-be parent type's field has `@fromContext` and one (or more) of this field's + // arguments doesn't exist in the would-be parent's field, rebasing would loose that + // context. + if field_definition.arguments.iter().any(|arg_definition| { + arg_definition + .directives + .has(from_context_directive_definition_name) + && !data + .arguments + .iter() + .any(|arg| arg.name == arg_definition.name) + }) { return Ok(None); - }; - Ok(Some(schema.get_type(type_name.clone())?.try_into()?)) - } else { - Ok(None) + } } + Ok(Some( + schema + .get_type(field_definition.ty.inner_named_type().clone())? + .try_into()?, + )) } } diff --git a/apollo-federation/src/query_graph/build_query_graph.rs b/apollo-federation/src/query_graph/build_query_graph.rs index fa8da0cec8..81cd361f4f 100644 --- a/apollo-federation/src/query_graph/build_query_graph.rs +++ b/apollo-federation/src/query_graph/build_query_graph.rs @@ -1,6 +1,5 @@ use std::sync::Arc; -use apollo_compiler::collections::HashMap; use apollo_compiler::collections::IndexMap; use apollo_compiler::collections::IndexSet; use apollo_compiler::schema::DirectiveList as ComponentDirectiveList; @@ -8,12 +7,15 @@ use apollo_compiler::schema::ExtendedType; use apollo_compiler::validation::Valid; use apollo_compiler::Name; use apollo_compiler::Schema; +use itertools::Itertools; use petgraph::graph::EdgeIndex; use petgraph::graph::NodeIndex; use petgraph::visit::EdgeRef; use petgraph::Direction; +use regex::Regex; use strum::IntoEnumIterator; +use crate::bail; use crate::error::FederationError; use crate::error::SingleFederationError; use crate::link::federation_spec_definition::get_federation_spec_definition_from_subgraph; @@ -22,6 +24,7 @@ use crate::link::federation_spec_definition::KeyDirectiveArguments; use crate::operation::merge_selection_sets; use crate::operation::Selection; use crate::operation::SelectionSet; +use crate::query_graph::ContextCondition; use crate::query_graph::OverrideCondition; use crate::query_graph::QueryGraph; use crate::query_graph::QueryGraphEdge; @@ -33,6 +36,7 @@ use crate::schema::position::AbstractTypeDefinitionPosition; use crate::schema::position::CompositeTypeDefinitionPosition; use crate::schema::position::FieldDefinitionPosition; use crate::schema::position::InterfaceTypeDefinitionPosition; +use crate::schema::position::ObjectFieldArgumentDefinitionPosition; use crate::schema::position::ObjectFieldDefinitionPosition; use crate::schema::position::ObjectOrInterfaceTypeDefinitionPosition; use crate::schema::position::ObjectTypeDefinitionPosition; @@ -43,6 +47,7 @@ use crate::schema::position::TypeDefinitionPosition; use crate::schema::position::UnionTypeDefinitionPosition; use crate::schema::ValidFederationSchema; use crate::supergraph::extract_subgraphs_from_supergraph; +use crate::utils::FallibleIterator; /// Builds a "federated" query graph based on the provided supergraph and API schema. /// @@ -59,7 +64,7 @@ pub fn build_federated_query_graph( for_query_planning: Option, ) -> Result { let for_query_planning = for_query_planning.unwrap_or(true); - let mut query_graph = QueryGraph { + let query_graph = QueryGraph { // Note this name is a dummy initial name that gets overridden as we build the query graph. current_source: "".into(), graph: Default::default(), @@ -68,22 +73,23 @@ pub fn build_federated_query_graph( types_to_nodes_by_source: Default::default(), root_kinds_to_nodes_by_source: Default::default(), non_trivial_followup_edges: Default::default(), + subgraph_to_args: Default::default(), + subgraph_to_arg_indices: Default::default(), }; - let subgraphs = - extract_subgraphs_from_supergraph(&supergraph_schema, validate_extracted_subgraphs)?; - for (subgraph_name, subgraph) in subgraphs { - let builder = SchemaQueryGraphBuilder::new( - query_graph, - subgraph_name, - subgraph.schema, - Some(api_schema.clone()), - for_query_planning, - )?; - query_graph = builder.build()?; - } - let federated_builder = FederatedQueryGraphBuilder::new(query_graph, supergraph_schema)?; - query_graph = federated_builder.build()?; - Ok(query_graph) + let query_graph = + extract_subgraphs_from_supergraph(&supergraph_schema, validate_extracted_subgraphs)? + .into_iter() + .fallible_fold(query_graph, |query_graph, (subgraph_name, subgraph)| { + SchemaQueryGraphBuilder::new( + query_graph, + subgraph_name, + subgraph.schema, + Some(api_schema.clone()), + for_query_planning, + )? + .build() + })?; + FederatedQueryGraphBuilder::new(query_graph, supergraph_schema)?.build() } /// Builds a query graph based on the provided schema (usually an API schema outside of testing). @@ -102,6 +108,8 @@ pub fn build_query_graph( types_to_nodes_by_source: Default::default(), root_kinds_to_nodes_by_source: Default::default(), non_trivial_followup_edges: Default::default(), + subgraph_to_args: Default::default(), + subgraph_to_arg_indices: Default::default(), }; let builder = SchemaQueryGraphBuilder::new(query_graph, name, schema, None, false)?; query_graph = builder.build()?; @@ -136,15 +144,9 @@ impl BaseQueryGraphBuilder { transition: QueryGraphEdgeTransition, conditions: Option>, ) -> Result<(), FederationError> { - self.query_graph.graph.add_edge( - head, - tail, - QueryGraphEdge { - transition, - conditions, - override_condition: None, - }, - ); + self.query_graph + .graph + .add_edge(head, tail, QueryGraphEdge::new(transition, conditions)); let head_weight = self.query_graph.node_weight(head)?; let tail_weight = self.query_graph.node_weight(tail)?; if head_weight.source != tail_weight.source { @@ -986,6 +988,7 @@ impl FederatedQueryGraphBuilder { self.handle_key()?; self.handle_requires()?; self.handle_progressive_overrides()?; + self.handle_context()?; // Note that @provides must be handled last when building since it requires copying nodes // and their edges, and it's easier to reason about this if we know previous self.handle_provides()?; @@ -1011,15 +1014,14 @@ impl FederatedQueryGraphBuilder { } fn add_federated_root_nodes(&mut self) -> Result<(), FederationError> { - let mut root_kinds = IndexSet::default(); - for (source, root_kinds_to_nodes) in &self.base.query_graph.root_kinds_to_nodes_by_source { - if *source == self.base.query_graph.current_source { - continue; - } - for root_kind in root_kinds_to_nodes.keys() { - root_kinds.insert(*root_kind); - } - } + let root_kinds = self + .base + .query_graph + .root_kinds_to_nodes_by_source + .iter() + .filter(|(source, _)| **source != self.base.query_graph.current_source) + .flat_map(|(_, root_kind_to_nodes)| root_kind_to_nodes.keys().copied()) + .collect::>(); for root_kind in root_kinds { self.base.create_root_node(root_kind.into(), root_kind)?; } @@ -1385,7 +1387,7 @@ impl FederatedQueryGraphBuilder { /// override condition of `false`, whereas the "to" subgraph will have an /// override condition of `true`. fn handle_progressive_overrides(&mut self) -> Result<(), FederationError> { - let mut edge_to_conditions: HashMap = Default::default(); + let mut edge_to_conditions: IndexMap = Default::default(); fn collect_edge_condition( query_graph: &QueryGraph, @@ -1393,7 +1395,7 @@ impl FederatedQueryGraphBuilder { target_field: &ObjectFieldDefinitionPosition, label: &str, condition: bool, - edge_to_conditions: &mut HashMap, + edge_to_conditions: &mut IndexMap, ) -> Result<(), FederationError> { let target_field = FieldDefinitionPosition::Object(target_field.clone()); let subgraph_nodes = query_graph @@ -1474,6 +1476,173 @@ impl FederatedQueryGraphBuilder { Ok(()) } + fn handle_context(&mut self) -> Result<(), FederationError> { + let mut subgraph_to_args: IndexMap, Vec> = + IndexMap::default(); + let mut coordinate_map: IndexMap< + Arc, + IndexMap>, + > = IndexMap::default(); + for (subgraph_name, subgraph) in self.base.query_graph.subgraphs() { + let subgraph_data = self.subgraphs.get(subgraph_name)?; + let Some((_, context_refs)) = &subgraph + .referencers() + .directives + .iter() + .find(|(dir, _)| **dir == subgraph_data.context_directive_definition_name) + else { + continue; + }; + + let Some((_, from_context_refs)) = &subgraph + .referencers() + .directives + .iter() + .find(|(dir, _)| **dir == subgraph_data.from_context_directive_definition_name) + else { + continue; + }; + + // Collect data for @context + let mut context_name_to_types: IndexMap< + &str, + IndexSet, + > = Default::default(); + for object_def_pos in &context_refs.object_types { + let object = object_def_pos.get(subgraph.schema())?; + for dir in object + .directives + .get_all(subgraph_data.context_directive_definition_name.as_str()) + { + let application = FederationSpecDefinition::context_directive_arguments(dir)?; + context_name_to_types + .entry(application.name) + .or_default() + .insert(object_def_pos.clone().into()); + } + } + for interface_def_pos in &context_refs.interface_types { + let interface = interface_def_pos.get(subgraph.schema())?; + for dir in interface + .directives + .get_all(subgraph_data.context_directive_definition_name.as_str()) + { + let application = FederationSpecDefinition::context_directive_arguments(dir)?; + context_name_to_types + .entry(application.name) + .or_default() + .insert(interface_def_pos.clone().into()); + } + } + for union_def_pos in &context_refs.union_types { + let union = union_def_pos.get(subgraph.schema())?; + for dir in union + .directives + .get_all(subgraph_data.context_directive_definition_name.as_str()) + { + let application = FederationSpecDefinition::context_directive_arguments(dir)?; + context_name_to_types + .entry(application.name) + .or_default() + .insert(union_def_pos.clone().into()); + } + } + + // Collect data for @fromContext + let coordinate_map = coordinate_map.entry(subgraph_name.clone()).or_default(); + for object_field_arg in &from_context_refs.object_field_arguments { + let input_value = object_field_arg.get(subgraph.schema())?; + subgraph_to_args + .entry(subgraph_name.clone()) + .or_default() + .push(object_field_arg.clone()); + let field_coordinate = object_field_arg.parent(); + if let Some(dir) = input_value.directives.get( + subgraph_data + .from_context_directive_definition_name + .as_str(), + ) { + let application = subgraph_data + .federation_spec_definition + .from_context_directive_arguments(dir)?; + let (context, selection) = parse_context(application.field)?; + + let types_with_context_set = context_name_to_types + .get(context.as_str()) + .into_iter() + .flatten() + .cloned() + .collect(); + let conditions = ContextCondition { + context, + selection, + subgraph_name: subgraph_name.clone(), + argument_coordinate: object_field_arg.clone(), + types_with_context_set, + named_parameter: object_field_arg.argument_name.to_owned(), + arg_type: input_value.ty.clone(), + }; + coordinate_map + .entry(field_coordinate.clone()) + .or_default() + .push(conditions); + } + } + } + + for edge in self.base.query_graph.graph.edge_indices() { + let edge_weight = self.base.query_graph.edge_weight(edge)?; + let QueryGraphEdgeTransition::FieldCollection { + source, + field_definition_position, + .. + } = &edge_weight.transition + else { + continue; + }; + let FieldDefinitionPosition::Object(obj_field) = field_definition_position else { + continue; + }; + let Some(contexts) = coordinate_map.get_mut(source) else { + continue; + }; + let Some(required_contexts) = contexts.get(obj_field) else { + continue; + }; + self.base + .query_graph + .edge_weight_mut(edge)? + .required_contexts + .extend_from_slice(required_contexts); + } + + // Add the context argument mapping + self.base.query_graph.subgraph_to_arg_indices = self + .base + .query_graph + .subgraphs() + .filter_map(|(source, _)| subgraph_to_args.get_full(source)) + .map(|(index, source, args)| { + Ok::<_, FederationError>(( + source.clone(), + args.iter() + .sorted() + .enumerate() + .map(|(i, arg)| { + Ok::<_, FederationError>(( + arg.clone(), + format!("contextualArgument_{}_{}", index + 1, i).try_into()?, + )) + }) + .process_results(|r| r.collect())?, + )) + }) + .process_results(|r| r.collect())?; + self.base.query_graph.subgraph_to_args = subgraph_to_args; + + Ok(()) + } + /// Handle @provides by copying the appropriate nodes/edges. fn handle_provides(&mut self) -> Result<(), FederationError> { let mut provide_id = 0; @@ -2083,6 +2252,14 @@ impl FederatedQueryGraphBuilderSubgraphs { .override_directive_definition(schema)? .name .clone(); + let context_directive_definition_name = federation_spec_definition + .context_directive_definition(schema)? + .name + .clone(); + let from_context_directive_definition_name = federation_spec_definition + .from_context_directive_definition(schema)? + .name + .clone(); subgraphs.map.insert( source.clone(), FederatedQueryGraphBuilderSubgraphData { @@ -2092,6 +2269,8 @@ impl FederatedQueryGraphBuilderSubgraphs { provides_directive_definition_name, interface_object_directive_definition_name, overrides_directive_definition_name, + context_directive_definition_name, + from_context_directive_definition_name, }, ); } @@ -2118,6 +2297,8 @@ struct FederatedQueryGraphBuilderSubgraphData { provides_directive_definition_name: Name, interface_object_directive_definition_name: Name, overrides_directive_definition_name: Name, + context_directive_definition_name: Name, + from_context_directive_definition_name: Name, } #[derive(Debug)] @@ -2151,6 +2332,45 @@ fn resolvable_key_applications<'doc>( Ok(applications) } +fn parse_context(field: &str) -> Result<(String, String), FederationError> { + let pattern = Regex::new( + r#"^(?:[\n\r\t ,]|#[^\n\r]*)*\$(?:[\n\r\t ,]|#[^\n\r]*)*([A-Za-z_]\w*)([\s\S]*)$"#, + ) + .unwrap(); + + let mut iter = pattern.captures_iter(field); + + let Some(captures) = iter.next() else { + bail!("Expected to find the name of a context and a selection inside the field argument to `@fromContext`: {field:?}"); + }; + + if iter.next().is_some() { + bail!("Expected only one context and selection pair inside the field argument to `@fromContext`: {field:?}"); + } + + let (context, selection) = captures + .iter() + // Ignore the first match because it is always the whole matching substring + .skip(1) + .flatten() + .fold(("", ""), |(_, b), group| (b, group.as_str())); + + if context.is_empty() { + bail!("Expected to find the name of a context inside the field argument to `@fromContext`: {field:?}"); + } + + if selection.is_empty() { + bail!( + "Expected to find and a selection inside the field argument to `@fromContext`: {field:?}" + ); + } + + Ok(( + context.trim_end().to_owned(), + selection.trim_start().to_owned(), + )) +} + #[cfg(test)] mod tests { use apollo_compiler::collections::IndexMap; @@ -2253,6 +2473,43 @@ mod tests { Ok(tails.pop().unwrap()) } + #[test] + fn test_parse_context() { + let fields = [ + ("$context { prop }", ("context", "{ prop }")), + ( + "$context ... on A { prop } ... on B { prop }", + ("context", "... on A { prop } ... on B { prop }"), + ), + ( + "$topLevelQuery { me { locale } }", + ("topLevelQuery", "{ me { locale } }"), + ), + ( + "$context { a { b { c { prop }}} }", + ("context", "{ a { b { c { prop }}} }"), + ), + ( + "$ctx { identifiers { legacyUserId } }", + ("ctx", "{ identifiers { legacyUserId } }"), + ), + ( + "$retailCtx { identifiers { id5 } }", + ("retailCtx", "{ identifiers { id5 } }"), + ), + ("$retailCtx { mid }", ("retailCtx", "{ mid }")), + ( + "$widCtx { identifiers { wid } }", + ("widCtx", "{ identifiers { wid } }"), + ), + ]; + for (field, (known_context, known_selection)) in fields { + let (context, selection) = super::parse_context(field).unwrap(); + assert_eq!(context, known_context); + assert_eq!(selection, known_selection); + } + } + #[test] fn building_query_graphs_from_schema_handles_object_types() -> Result<(), FederationError> { let query_graph = test_query_graph_from_schema_sdl( diff --git a/apollo-federation/src/query_graph/condition_resolver.rs b/apollo-federation/src/query_graph/condition_resolver.rs index e547f2a235..c9f3b0da66 100644 --- a/apollo-federation/src/query_graph/condition_resolver.rs +++ b/apollo-federation/src/query_graph/condition_resolver.rs @@ -3,16 +3,31 @@ // trait directly using `ConditionResolverCache`. use std::sync::Arc; +use apollo_compiler::ast::Type; use apollo_compiler::collections::IndexMap; +use apollo_compiler::Name; +use apollo_compiler::Node; use petgraph::graph::EdgeIndex; use crate::error::FederationError; +use crate::operation::SelectionSet; use crate::query_graph::graph_path::ExcludedConditions; use crate::query_graph::graph_path::ExcludedDestinations; use crate::query_graph::graph_path::OpGraphPathContext; use crate::query_graph::path_tree::OpPathTree; use crate::query_plan::QueryPlanCost; +#[derive(Debug, Clone)] +pub(crate) struct ContextMapEntry { + pub(crate) levels_in_data_path: usize, + pub(crate) levels_in_query_path: usize, + pub(crate) path_tree: Option>, + pub(crate) selection_set: SelectionSet, + pub(crate) param_name: Name, + pub(crate) arg_type: Node, + pub(crate) id: Name, +} + /// Note that `ConditionResolver`s are guaranteed to be only called for edge with conditions. pub(crate) trait ConditionResolver { fn resolve( @@ -21,6 +36,7 @@ pub(crate) trait ConditionResolver { context: &OpGraphPathContext, excluded_destinations: &ExcludedDestinations, excluded_conditions: &ExcludedConditions, + extra_conditions: Option<&SelectionSet>, ) -> Result; } @@ -29,6 +45,7 @@ pub(crate) enum ConditionResolution { Satisfied { cost: QueryPlanCost, path_tree: Option>, + context_map: Option>, }, Unsatisfied { // NOTE: This seems to be a false positive... @@ -40,6 +57,7 @@ pub(crate) enum ConditionResolution { #[derive(Debug, Clone)] pub(crate) enum UnsatisfiedConditionReason { NoPostRequireKey, + NoSetContext, } impl ConditionResolution { @@ -47,6 +65,7 @@ impl ConditionResolution { Self::Satisfied { cost: 0.0, path_tree: None, + context_map: None, } } @@ -91,7 +110,11 @@ impl ConditionResolverCache { context: &OpGraphPathContext, excluded_destinations: &ExcludedDestinations, excluded_conditions: &ExcludedConditions, + extra_conditions: Option<&SelectionSet>, ) -> ConditionResolutionCacheResult { + if extra_conditions.is_some() { + return ConditionResolutionCacheResult::NotApplicable; + } // We don't cache if there is a context or excluded conditions because those would impact the resolution and // we don't want to cache a value per-context and per-excluded-conditions (we also don't cache per-excluded-edges though // instead we cache a value only for the first-see excluded edges; see above why that work in practice). @@ -150,7 +173,8 @@ mod tests { edge1, &empty_context, &empty_destinations, - &empty_conditions + &empty_conditions, + None ) .is_miss()); @@ -165,7 +189,8 @@ mod tests { edge1, &empty_context, &empty_destinations, - &empty_conditions + &empty_conditions, + None ) .is_hit(),); @@ -176,7 +201,8 @@ mod tests { edge2, &empty_context, &empty_destinations, - &empty_conditions + &empty_conditions, + None ) .is_miss()); } diff --git a/apollo-federation/src/query_graph/graph_path.rs b/apollo-federation/src/query_graph/graph_path.rs index c01e1753dc..3bf55adc7d 100644 --- a/apollo-federation/src/query_graph/graph_path.rs +++ b/apollo-federation/src/query_graph/graph_path.rs @@ -4,12 +4,18 @@ use std::fmt::Formatter; use std::fmt::Write; use std::hash::Hash; use std::ops::Deref; +use std::ops::DerefMut; use std::sync::atomic; use std::sync::Arc; +use apollo_compiler::ast::InputValueDefinition; +use apollo_compiler::ast::Type; use apollo_compiler::ast::Value; use apollo_compiler::collections::IndexMap; use apollo_compiler::collections::IndexSet; +use apollo_compiler::executable::Argument; +use apollo_compiler::Name; +use apollo_compiler::Node; use either::Either; use itertools::Itertools; use petgraph::graph::EdgeIndex; @@ -19,11 +25,14 @@ use petgraph::visit::EdgeRef; use tracing::debug; use tracing::debug_span; +use super::condition_resolver::ContextMapEntry; +use crate::bail; use crate::display_helpers::write_indented_lines; use crate::display_helpers::DisplayOption; use crate::display_helpers::DisplaySlice; use crate::display_helpers::State as IndentedFormatter; use crate::error::FederationError; +use crate::internal_error; use crate::is_leaf_type; use crate::link::federation_spec_definition::get_federation_spec_definition_from_subgraph; use crate::link::graphql_definition::BooleanOrVariable; @@ -34,8 +43,10 @@ use crate::operation::DirectiveList; use crate::operation::Field; use crate::operation::HasSelectionKey; use crate::operation::InlineFragment; +use crate::operation::NamedFragments; use crate::operation::SelectionId; use crate::operation::SelectionKey; +use crate::operation::SelectionMapperReturn; use crate::operation::SelectionSet; use crate::operation::SiblingTypename; use crate::query_graph::condition_resolver::ConditionResolution; @@ -48,9 +59,11 @@ use crate::query_graph::QueryGraphNodeType; use crate::query_plan::query_planner::EnabledOverrideConditions; use crate::query_plan::FetchDataPathElement; use crate::query_plan::QueryPlanCost; +use crate::schema::field_set::parse_field_set; use crate::schema::position::AbstractTypeDefinitionPosition; use crate::schema::position::Captures; use crate::schema::position::CompositeTypeDefinitionPosition; +use crate::schema::position::FieldDefinitionPosition; use crate::schema::position::InterfaceFieldDefinitionPosition; use crate::schema::position::ObjectOrInterfaceTypeDefinitionPosition; use crate::schema::position::ObjectTypeDefinitionPosition; @@ -58,6 +71,14 @@ use crate::schema::position::OutputTypeDefinitionPosition; use crate::schema::position::TypeDefinitionPosition; use crate::schema::ValidFederationSchema; +#[derive(Clone, serde::Serialize, Debug, Eq, PartialEq)] +pub(crate) struct ContextAtUsageEntry { + pub(crate) context_id: Name, + pub(crate) relative_path: Vec, + pub(crate) selection_set: SelectionSet, + pub(crate) subgraph_arg_type: Node, +} + /// An immutable path in a query graph. /// /// A "path" here is mostly understood in the graph-theoretical sense of the term, i.e. as "a @@ -157,6 +178,11 @@ where // TODO(@TylerBloom): Add in once defer is supported. #[serde(skip)] defer_on_tail: Option, + /// At the point where a `@context` is set, we will have fields to select + context_to_selection: Vec>, + /// Where a context is used (i.e. `@fromContext`) there will exist a ContextAtUsageEntry map + /// (1 for each parameter) + parameter_to_context: Vec>, } impl std::fmt::Debug for GraphPath @@ -183,6 +209,8 @@ where runtime_types_of_tail, runtime_types_before_tail_if_last_is_cast, defer_on_tail, + context_to_selection: _, + parameter_to_context: _, } = self; f.debug_struct("GraphPath") @@ -242,9 +270,17 @@ impl OverrideId { } } +pub(crate) type ContextToSelection = IndexSet; +pub(crate) type ParameterToContext = IndexMap; + /// The item type for [`GraphPath::iter`] -pub(crate) type GraphPathItem<'path, TTrigger, TEdge> = - (TEdge, &'path Arc, &'path Option>); +pub(crate) type GraphPathItem<'path, TTrigger, TEdge> = ( + TEdge, + &'path Arc, + &'path Option>, + Option, + Option, +); /// A `GraphPath` whose triggers are operation elements (essentially meaning that the path has been /// guided by a GraphQL operation). @@ -854,9 +890,123 @@ where } } +impl TryFrom for Arc { + type Error = FederationError; + + fn try_from(value: GraphPathTrigger) -> Result { + match value { + GraphPathTrigger::Op(op) => Ok(op), + GraphPathTrigger::Transition(_) => { + bail!("Failed to convert to GraphPathTrigger") + } + } + } +} + +impl TryFrom for Arc { + type Error = FederationError; + + fn try_from(value: GraphPathTrigger) -> Result { + match value { + GraphPathTrigger::Transition(transition) => Ok(transition), + GraphPathTrigger::Op(_) => Err(FederationError::internal( + "Failed to convert to GraphPathTrigger", + )), + } + } +} + +pub(crate) enum GraphPathTriggerRef<'a> { + Op(&'a OpGraphPathTrigger), + Transition(&'a QueryGraphEdgeTransition), +} + +pub(crate) enum GraphPathTriggerRefMut<'a> { + Op(&'a mut OpGraphPathTrigger), + Transition(&'a mut QueryGraphEdgeTransition), +} + +impl<'a> From<&'a GraphPathTrigger> for GraphPathTriggerRef<'a> { + fn from(value: &'a GraphPathTrigger) -> Self { + match value { + GraphPathTrigger::Op(value) => value.as_ref().into(), + GraphPathTrigger::Transition(value) => value.as_ref().into(), + } + } +} + +impl<'a> From<&'a OpGraphPathTrigger> for GraphPathTriggerRef<'a> { + fn from(value: &'a OpGraphPathTrigger) -> Self { + Self::Op(value) + } +} + +impl<'a> From<&'a mut OpGraphPathTrigger> for GraphPathTriggerRefMut<'a> { + fn from(value: &'a mut OpGraphPathTrigger) -> Self { + Self::Op(value) + } +} + +impl<'a> From<&'a QueryGraphEdgeTransition> for GraphPathTriggerRef<'a> { + fn from(value: &'a QueryGraphEdgeTransition) -> Self { + Self::Transition(value) + } +} + +impl<'a> From<&'a mut QueryGraphEdgeTransition> for GraphPathTriggerRefMut<'a> { + fn from(value: &'a mut QueryGraphEdgeTransition) -> Self { + Self::Transition(value) + } +} + +/// `GraphPath` is generic over two type, `TTrigger` and `TEdge`. This trait helps abstract over +/// the `TTrigger` type bound. A `TTrigger` is one of the two types that make up the variants of +/// the `GraphPathTrigger`. Rather than trying to cast into concrete types and cast back (and +/// potentially raise errors), this trait provides ways to access the data needed within. +pub(crate) trait GraphPathTriggerVariant: Eq + Hash + std::fmt::Debug { + fn get_field_mut<'a>(&'a mut self) -> Option<&mut Field> + where + &'a mut Self: Into>, + { + match self.into() { + GraphPathTriggerRefMut::Op(OpGraphPathTrigger::OpPathElement( + OpPathElement::Field(field), + )) => Some(field), + _ => None, + } + } + + fn get_field_parent_type<'a>(&'a self) -> Option + where + &'a Self: Into>, + { + match self.into() { + GraphPathTriggerRef::Op(trigger) => match trigger { + OpGraphPathTrigger::OpPathElement(OpPathElement::Field(field)) => { + Some(field.field_position.clone()) + } + _ => None, + }, + GraphPathTriggerRef::Transition(trigger) => match trigger { + QueryGraphEdgeTransition::FieldCollection { + field_definition_position, + .. + } => Some(field_definition_position.clone()), + _ => None, + }, + } + } +} + +impl GraphPathTriggerVariant for OpGraphPathTrigger {} + +impl GraphPathTriggerVariant for QueryGraphEdgeTransition {} + impl GraphPath where - TTrigger: Eq + Hash + std::fmt::Debug, + TTrigger: GraphPathTriggerVariant, + for<'a> &'a TTrigger: Into>, + for<'a> &'a mut TTrigger: Into>, Arc: Into, TEdge: Copy + Into> + std::fmt::Debug, EdgeIndex: Into, @@ -875,6 +1025,8 @@ where runtime_types_of_tail: Arc::new(IndexSet::default()), runtime_types_before_tail_if_last_is_cast: None, defer_on_tail: None, + context_to_selection: Vec::default(), + parameter_to_context: Vec::default(), }; path.runtime_types_of_tail = Arc::new(path.head_possible_runtime_types()?); Ok(path) @@ -898,7 +1050,7 @@ where pub(crate) fn add( &self, - trigger: TTrigger, + mut trigger: TTrigger, edge: TEdge, condition_resolution: ConditionResolution, defer: Option, @@ -906,6 +1058,7 @@ where let ConditionResolution::Satisfied { path_tree: condition_path_tree, cost: condition_cost, + context_map, } = condition_resolution else { return Err(FederationError::internal( @@ -916,6 +1069,8 @@ where let mut edges = self.edges.clone(); let mut edge_triggers = self.edge_triggers.clone(); let mut edge_conditions = self.edge_conditions.clone(); + let mut context_to_selection = self.context_to_selection.clone(); + let mut parameter_to_context = self.parameter_to_context.clone(); let mut last_subgraph_entering_edge_info = if defer.is_none() { self.last_subgraph_entering_edge_info.clone() } else { @@ -926,6 +1081,8 @@ where edges.push(edge); edge_triggers.push(Arc::new(trigger)); edge_conditions.push(condition_path_tree); + context_to_selection.push(None); + parameter_to_context.push(None); return Ok(GraphPath { graph: self.graph.clone(), head: self.head, @@ -945,6 +1102,8 @@ where ), runtime_types_before_tail_if_last_is_cast: None, defer_on_tail: defer, + context_to_selection, + parameter_to_context, }); }; @@ -1082,6 +1241,8 @@ where } else { self.defer_on_tail.clone() }, + context_to_selection: self.context_to_selection.clone(), + parameter_to_context: self.parameter_to_context.clone(), }); } } @@ -1142,13 +1303,72 @@ where // We know last edge is not a cast. runtime_types_before_tail_if_last_is_cast: None, defer_on_tail: defer, + context_to_selection: self.context_to_selection.clone(), + parameter_to_context: self.parameter_to_context.clone(), }); } } + let (new_edge_conditions, new_context_to_selection, new_parameter_to_context) = + self.merge_edge_conditions_with_resolution(&condition_path_tree, &context_map); + let last_parameter_to_context = new_parameter_to_context.last(); + + if let Some(Some(last_parameter_to_context)) = last_parameter_to_context { + // TODO: Perhaps it is better to explicitly cast this to `GraphPathTriggerRefMut` and + // pull out the field from there. + if let Some(field) = trigger.get_field_mut() { + let mut schema = field.schema.schema().clone().into_inner(); + let type_name = field.field_position.type_name(); + let field_name = field.field_position.field_name(); + let Some(field_def) = schema.types.get_mut(type_name).and_then(|t| match t { + apollo_compiler::schema::ExtendedType::Scalar(_) => None, + apollo_compiler::schema::ExtendedType::Object(obj) => { + obj.make_mut().fields.get_mut(field_name) + } + apollo_compiler::schema::ExtendedType::Interface(iface) => { + iface.make_mut().fields.get_mut(field_name) + } + apollo_compiler::schema::ExtendedType::Union(_) => None, + apollo_compiler::schema::ExtendedType::Enum(_) => None, + apollo_compiler::schema::ExtendedType::InputObject(_) => None, + }) else { + bail!("Unexpectedly failed to lookup field {type_name}.{field_name}") + }; + let field_def = field_def.deref_mut().make_mut(); + let mut updated_field_arguments = vec![]; + let mut updated_field_def_arguments = vec![]; + for (param_name, usage_entry) in last_parameter_to_context { + if !field_def + .arguments + .iter() + .any(|arg| arg.name.as_str() == param_name.as_str()) + { + updated_field_def_arguments.push(Node::new(InputValueDefinition { + name: usage_entry.context_id.clone(), + ty: usage_entry.subgraph_arg_type.clone(), + default_value: None, + description: None, + directives: Default::default(), + })); + updated_field_arguments.push(Node::new(Argument { + name: param_name.clone(), + value: Node::new(Value::Variable(usage_entry.context_id.clone())), + })); + } + } + field_def.arguments.extend(updated_field_def_arguments); + field.schema = ValidFederationSchema::new(schema.validate()?)?; + field.arguments = field + .arguments + .iter() + .cloned() + .chain(updated_field_arguments) + .collect(); + } + } + edges.push(edge); edge_triggers.push(Arc::new(trigger)); - edge_conditions.push(condition_path_tree); if defer.is_none() && self.graph.is_cross_subgraph_edge(new_edge)? { last_subgraph_entering_edge_info = Some(SubgraphEnteringEdgeInfo { index: self.edges.len(), @@ -1161,7 +1381,7 @@ where tail: edge_tail, edges, edge_triggers, - edge_conditions, + edge_conditions: new_edge_conditions, // Again, we don't want to set `last_subgraph_entering_edge_info` if we're entering a // `@defer` (see above). last_subgraph_entering_edge_info, @@ -1193,18 +1413,88 @@ where } else { None }, + context_to_selection: new_context_to_selection, + parameter_to_context: new_parameter_to_context, }) } + #[allow(clippy::type_complexity)] + fn merge_edge_conditions_with_resolution( + &self, + condition_path_tree: &Option>, + context_map: &Option>, + ) -> ( + Vec>>, + Vec>>, + Vec>>, + ) { + let mut edge_conditions = self.edge_conditions.clone(); + let mut context_to_selection = self.context_to_selection.clone(); + let mut parameter_to_context = self.parameter_to_context.clone(); + + edge_conditions.push(condition_path_tree.clone()); + if context_map.is_none() || context_map.as_ref().is_some_and(|m| m.is_empty()) { + context_to_selection.push(None); + parameter_to_context.push(None); + (edge_conditions, context_to_selection, parameter_to_context) + } else { + // parameter_to_context.push(Some(Arc::new(IndexMap::default()))); + context_to_selection.push(None); + let mut new_parameter_to_context = IndexMap::default(); + for (_, entry) in context_map.iter().flat_map(|map| map.iter()) { + let idx = edge_conditions.len() - entry.levels_in_query_path - 1; + + if let Some(path_tree) = &entry.path_tree { + let merged_conditions = edge_conditions[idx] + .as_ref() + .map_or_else(|| path_tree.clone(), |condition| condition.merge(path_tree)); + edge_conditions[idx] = Some(merged_conditions); + } + context_to_selection[idx] + .get_or_insert_with(Default::default) + .insert(entry.id.clone()); + + new_parameter_to_context.insert( + entry.param_name.clone(), + ContextAtUsageEntry { + context_id: entry.id.clone(), + relative_path: vec![ + FetchDataPathElement::Parent; + entry.levels_in_data_path + ], + selection_set: entry.selection_set.clone(), + subgraph_arg_type: entry.arg_type.clone(), + }, + ); + } + parameter_to_context.push(Some(new_parameter_to_context)); + (edge_conditions, context_to_selection, parameter_to_context) + } + } + pub(crate) fn iter(&self) -> impl Iterator> { debug_assert_eq!(self.edges.len(), self.edge_triggers.len()); debug_assert_eq!(self.edges.len(), self.edge_conditions.len()); + debug_assert_eq!(self.edges.len(), self.context_to_selection.len()); + debug_assert_eq!(self.edges.len(), self.parameter_to_context.len()); self.edges .iter() .copied() .zip(&self.edge_triggers) .zip(&self.edge_conditions) - .map(|((edge, trigger), condition)| (edge, trigger, condition)) + .zip(&self.context_to_selection) + .zip(&self.parameter_to_context) + .map( + |((((edge, trigger), condition), context_to_selection), parameter_to_context)| { + ( + edge, + trigger, + condition, + context_to_selection.clone(), + parameter_to_context.clone(), + ) + }, + ) } pub(crate) fn next_edges( @@ -1355,10 +1645,12 @@ where == Some(self.edges.len() - 2)) } + /* #[cfg_attr( feature = "snapshot_tracing", tracing::instrument(skip_all, level = "trace", name = "GraphPath::can_satisfy_conditions") )] + */ fn can_satisfy_conditions( &self, edge: EdgeIndex, @@ -1368,15 +1660,210 @@ where excluded_conditions: &ExcludedConditions, ) -> Result { let edge_weight = self.graph.edge_weight(edge)?; - if edge_weight.conditions.is_none() { + if edge_weight.conditions.is_none() && edge_weight.required_contexts.is_empty() { return Ok(ConditionResolution::no_conditions()); } + + /* Resolve context conditions */ + + let mut total_cost = 0.; + let mut context_map: IndexMap = IndexMap::default(); + + if !edge_weight.required_contexts.is_empty() { + let mut was_unsatisfied = false; + for ctx in &edge_weight.required_contexts { + let mut levels_in_data_path = 0; + for (mut levels_in_query_path, (e, trigger)) in self + .edges + .iter() + .zip(self.edge_triggers.iter()) + .rev() + .enumerate() + { + let parent_type = trigger.get_field_parent_type(); + levels_in_query_path += 1; + if parent_type.is_some() { + levels_in_data_path += 1; + } + let Some(e) = (*e).into() else { continue }; + if !was_unsatisfied && !context_map.contains_key(&ctx.named_parameter) { + if let Some(parent_type) = parent_type { + let parent_type = parent_type.parent(); + let subgraph_schema = + self.graph.schema_by_source(&ctx.subgraph_name)?; + let mut potential_matches: IndexSet = Default::default(); + ctx.types_with_context_set.iter().for_each(|pos| { + if pos.type_name() == parent_type.type_name() { + potential_matches.insert(parent_type.type_name().clone()); + } + match &pos { + CompositeTypeDefinitionPosition::Object(obj_pos) => { + if let Ok(obj) = obj_pos.get(subgraph_schema.schema()) { + obj.implements_interfaces + .iter() + .filter(|item| { + &item.name == parent_type.type_name() + }) + .for_each(|item| { + potential_matches.insert(item.name.clone()); + }); + } + } + CompositeTypeDefinitionPosition::Interface(iface_pos) => { + if let Ok(iface) = iface_pos.get(subgraph_schema.schema()) { + iface + .implements_interfaces + .iter() + .filter(|item| { + &item.name == parent_type.type_name() + }) + .for_each(|_| { + potential_matches.insert(iface.name.clone()); + }); + } + } + CompositeTypeDefinitionPosition::Union(union_pos) => { + if let Ok(un) = union_pos.get(subgraph_schema.schema()) { + un.members + .iter() + .filter(|item| { + &item.name == parent_type.type_name() + }) + .for_each(|_| { + potential_matches.insert(un.name.clone()); + }); + } + } + } + }); + + // get the selection set for the first match that parses + let selection_set = + potential_matches.iter().find_map(|parent_type_name| { + parse_field_set( + subgraph_schema, + parent_type_name.clone(), + &ctx.selection, + ) + .ok() + }); + + if let Some(selection_set) = selection_set { + selection_set.lazy_map( + &NamedFragments::default(), + |selection| { + if let OpPathElement::InlineFragment(fragment) = + selection.element()? + { + if let Some(CompositeTypeDefinitionPosition::Object( + obj, + )) = &fragment.type_condition_position + { + if !subgraph_schema + .possible_runtime_types(parent_type.clone())? + .contains(obj) + { + return Ok(SelectionMapperReturn::None); + } + } + } + Ok(SelectionMapperReturn::Selection(selection.clone())) + }, + )?; + let resolution = condition_resolver.resolve( + e, + context, + excluded_destinations, + excluded_conditions, + Some(&selection_set), + )?; + let Some(arg_indices) = + self.graph.subgraph_to_arg_indices.get(&ctx.subgraph_name) + else { + bail!("Unknown subgraph, {:?}, in QueryGraph::subgraph_to_arg_indices", ctx.subgraph_name) + }; + let Some(id) = arg_indices.get(&ctx.argument_coordinate).cloned() + else { + bail!("Unknown argument coordiate, {:?}, in QueryGraph::subgraph_to_arg_indices[{}]", ctx.argument_coordinate, ctx.subgraph_name) + }; + + match &resolution { + ConditionResolution::Satisfied { + cost, path_tree, .. + } => { + total_cost += cost; + let entry = ContextMapEntry { + levels_in_data_path, + levels_in_query_path, + path_tree: path_tree.clone(), + selection_set, + param_name: ctx.named_parameter.clone(), + arg_type: ctx.arg_type.clone(), + id, + }; + context_map.insert(ctx.named_parameter.clone(), entry); + } + ConditionResolution::Unsatisfied { .. } => { + was_unsatisfied = true + } + } + } else { + internal_error!( + "Could not parse selection {} over any types {:?}", + &ctx.selection, + potential_matches + ); + } + } + } + } + } + + if edge_weight + .required_contexts + .iter() + .any(|ctx| !context_map.contains_key(&ctx.named_parameter)) + { + debug!("@fromContext requires a context that is not set in graph path"); + return Ok(ConditionResolution::Unsatisfied { + reason: Some(UnsatisfiedConditionReason::NoSetContext), + }); + } + + if was_unsatisfied { + debug!("@fromContext selection set is unsatisfied"); + return Ok(ConditionResolution::Unsatisfied { reason: None }); + } + + // it's possible that we will need to create a new fetch group at this point, in which + // case we'll need to collect the keys to jump back to this object as a precondition + // for satisfying it. + let (edge_head, _) = self.graph.edge_endpoints(edge)?; + if self.graph.get_locally_satisfiable_key(edge_head)?.is_none() { + debug!("Post-context conditions cannot be satisfied"); + return Ok(ConditionResolution::Unsatisfied { + reason: Some(UnsatisfiedConditionReason::NoPostRequireKey), + }); + } + + if edge_weight.conditions.is_none() { + return Ok(ConditionResolution::Satisfied { + cost: total_cost, + path_tree: None, + context_map: Some(context_map), + }); + } + } + + /* Resolve all other conditions */ + debug_span!("Checking conditions {conditions} on edge {edge_weight}"); - let resolution = condition_resolver.resolve( + let mut resolution = condition_resolver.resolve( edge, context, excluded_destinations, excluded_conditions, + None, )?; if let Some(Some(last_edge)) = self.edges.last().map(|e| (*e).into()) { if matches!( @@ -1428,6 +1915,13 @@ where } } } + if let ConditionResolution::Satisfied { + context_map: ctx_map, + .. + } = &mut resolution + { + *ctx_map = Some(context_map); + } debug!("Condition resolution: {resolution:?}"); Ok(resolution) } @@ -1597,7 +2091,12 @@ where &excluded_destinations.add_excluded(&edge_tail_weight.source), excluded_conditions, )?; - if let ConditionResolution::Satisfied { path_tree, cost } = condition_resolution { + if let ConditionResolution::Satisfied { + path_tree, + cost, + context_map, + } = condition_resolution + { debug!("Condition satisfied"); drop(guard); // We can get to `edge_tail_weight.source` with that edge. But if we had already @@ -1784,7 +2283,11 @@ where let updated_path = Arc::new(to_advance.add( transition_and_context_to_trigger(&edge_weight.transition, context), edge.into(), - ConditionResolution::Satisfied { cost, path_tree }, + ConditionResolution::Satisfied { + cost, + path_tree, + context_map, + }, None, )?); best_path_by_source.insert( @@ -2183,6 +2686,8 @@ impl OpGraphPath { runtime_types_before_tail_if_last_is_cast: None, // TODO: The JS codebase copied this from the current path, which seems like a bug. defer_on_tail: self.defer_on_tail.clone(), + context_to_selection: self.context_to_selection.clone(), + parameter_to_context: self.parameter_to_context.clone(), }) } @@ -3931,6 +4436,7 @@ mod tests { ConditionResolution::Satisfied { cost: 0.0, path_tree: None, + context_map: None, }, None, ) @@ -3949,6 +4455,7 @@ mod tests { ConditionResolution::Satisfied { cost: 0.0, path_tree: None, + context_map: None, }, None, ) diff --git a/apollo-federation/src/query_graph/mod.rs b/apollo-federation/src/query_graph/mod.rs index 736f7af567..cb21e80a95 100644 --- a/apollo-federation/src/query_graph/mod.rs +++ b/apollo-federation/src/query_graph/mod.rs @@ -6,7 +6,9 @@ use std::sync::Arc; use apollo_compiler::collections::IndexMap; use apollo_compiler::collections::IndexSet; use apollo_compiler::schema::NamedType; +use apollo_compiler::schema::Type; use apollo_compiler::Name; +use apollo_compiler::Node; use petgraph::graph::DiGraph; use petgraph::graph::EdgeIndex; use petgraph::graph::EdgeReference; @@ -24,6 +26,7 @@ use crate::schema::field_set::parse_field_set; use crate::schema::position::CompositeTypeDefinitionPosition; use crate::schema::position::FieldDefinitionPosition; use crate::schema::position::InterfaceFieldDefinitionPosition; +use crate::schema::position::ObjectFieldArgumentDefinitionPosition; use crate::schema::position::ObjectTypeDefinitionPosition; use crate::schema::position::OutputTypeDefinitionPosition; use crate::schema::position::SchemaRootDefinitionKind; @@ -131,6 +134,20 @@ impl TryFrom for ObjectTypeDefinitionPosition { } } +/// Contains all of the data necessary to connect the object field (`coordinate`) with the +/// `@fromContext` to its (grand)parent types contain a matching selection. +#[derive(Debug, PartialEq, Clone)] +pub struct ContextCondition { + context: String, + subgraph_name: Arc, + selection: String, + types_with_context_set: IndexSet, + // PORT_NOTE: This field was renamed because the JS name (`coordinate`) was too vague. + argument_coordinate: ObjectFieldArgumentDefinitionPosition, + named_parameter: Name, + arg_type: Node, +} + #[derive(Debug, PartialEq, Clone)] pub(crate) struct QueryGraphEdge { /// Indicates what kind of edge this is and what the edge does/represents. For instance, if the @@ -155,9 +172,24 @@ pub(crate) struct QueryGraphEdge { /// one of them has an @override with a label. If the override condition /// matches the query plan parameters, this edge can be taken. pub(crate) override_condition: Option, + /// All fields with `@fromContext` that need access to parental type with corresponding + /// `@context`. + pub(crate) required_contexts: Vec, } impl QueryGraphEdge { + pub(crate) fn new( + transition: QueryGraphEdgeTransition, + conditions: Option>, + ) -> Self { + Self { + transition, + conditions, + override_condition: None, + required_contexts: Vec::new(), + } + } + fn satisfies_override_conditions( &self, conditions_to_check: &EnabledOverrideConditions, @@ -357,6 +389,11 @@ pub struct QueryGraph { /// lowered composition validation on a big composition (100+ subgraphs) from ~4 minutes to /// ~10 seconds. non_trivial_followup_edges: IndexMap>, + /// Maps each subgraph name to each field argument of `@fromContext`. + pub(crate) subgraph_to_args: IndexMap, Vec>, + /// Like `self.subgraph_to_args` but pairs each field argument with a unique identifier string. + pub(crate) subgraph_to_arg_indices: + IndexMap, IndexMap>, } impl QueryGraph { @@ -599,6 +636,7 @@ impl QueryGraph { &OpGraphPathContext::default(), &ExcludedDestinations::default(), &ExcludedConditions::default(), + None, )?; let ConditionResolution::Satisfied { cost, .. } = condition_resolution else { continue; diff --git a/apollo-federation/src/query_graph/path_tree.rs b/apollo-federation/src/query_graph/path_tree.rs index cf758bed37..b4f4e820cb 100644 --- a/apollo-federation/src/query_graph/path_tree.rs +++ b/apollo-federation/src/query_graph/path_tree.rs @@ -9,6 +9,8 @@ use petgraph::graph::EdgeIndex; use petgraph::graph::NodeIndex; use serde::Serialize; +use super::graph_path::ContextToSelection; +use super::graph_path::ParameterToContext; use crate::error::FederationError; use crate::operation::SelectionSet; use crate::query_graph::graph_path::GraphPathItem; @@ -92,6 +94,10 @@ where pub(crate) conditions: Option>, /// The child `PathTree` reached by taking the edge. pub(crate) tree: Arc>, + // a list of contexts set at this point in the path tree + pub(crate) context_to_selection: Option, + // a list of contexts used at this point in the path tree + pub(crate) parameter_to_context: Option, } impl PartialEq for PathTreeChild @@ -242,12 +248,21 @@ where trigger: &'inputs Arc, conditions: Option>, sub_paths_and_selections: Vec<(GraphPathIter, Option<&'inputs Arc>)>, + context_to_selection: Option, + parameter_to_context: Option, } let mut local_selection_sets = Vec::new(); for (mut graph_path_iter, selection) in graph_paths_and_selections { - let Some((generic_edge, trigger, conditions)) = graph_path_iter.next() else { + let Some(( + generic_edge, + trigger, + conditions, + context_to_selection, + parameter_to_context, + )) = graph_path_iter.next() + else { // End of an input `GraphPath` if let Some(selection) = selection { local_selection_sets.push(selection.clone()); @@ -274,6 +289,18 @@ where let existing = entry.into_mut(); existing.trigger = trigger; existing.conditions = merge_conditions(&existing.conditions, conditions); + if let Some(other) = context_to_selection { + existing + .context_to_selection + .get_or_insert_with(Default::default) + .extend(other); + } + if let Some(other) = parameter_to_context { + existing + .parameter_to_context + .get_or_insert_with(IndexMap::default) + .extend(other); + } existing .sub_paths_and_selections .push((graph_path_iter, selection)) @@ -284,6 +311,8 @@ where trigger, conditions: conditions.clone(), sub_paths_and_selections: vec![(graph_path_iter, selection)], + context_to_selection, + parameter_to_context, }); } } @@ -301,6 +330,8 @@ where by_unique_edge.target_node, child.sub_paths_and_selections, )?), + context_to_selection: child.context_to_selection.clone(), + parameter_to_context: child.parameter_to_context.clone(), })) } } @@ -334,6 +365,8 @@ where (Some(cond_a), Some(cond_b)) => cond_a.equals_same_root(cond_b), _ => false, } + && a.context_to_selection == b.context_to_selection + && a.parameter_to_context == b.parameter_to_context && a.tree.equals_same_root(&b.tree) }) } @@ -415,6 +448,14 @@ where trigger: child.trigger.clone(), conditions: merge_conditions(&child.conditions, &other_child.conditions), tree: child.tree.merge(&other_child.tree), + context_to_selection: merge_context_to_selection( + &child.context_to_selection, + &other_child.context_to_selection, + ), + parameter_to_context: merge_parameter_to_context( + &child.parameter_to_context, + &other_child.parameter_to_context, + ), }) } else { childs.push(other_child.clone()) @@ -436,6 +477,40 @@ where } } +fn merge_context_to_selection( + a: &Option, + b: &Option, +) -> Option { + match (a, b) { + (Some(a), Some(b)) => { + let mut merged: ContextToSelection = Default::default(); + merged.extend(a.iter().cloned()); + merged.extend(b.iter().cloned()); + Some(merged) + } + (Some(a), None) => Some(a.clone()), + (None, Some(b)) => Some(b.clone()), + (None, None) => None, + } +} + +fn merge_parameter_to_context( + a: &Option, + b: &Option, +) -> Option { + match (a, b) { + (Some(a), Some(b)) => { + let mut merged: ParameterToContext = Default::default(); + merged.extend(a.iter().map(|(k, v)| (k.clone(), v.clone()))); + merged.extend(b.iter().map(|(k, v)| (k.clone(), v.clone()))); + Some(merged) + } + (Some(a), None) => Some(a.clone()), + (None, Some(b)) => Some(b.clone()), + (None, None) => None, + } +} + fn merge_conditions( a: &Option>, b: &Option>, @@ -507,6 +582,7 @@ mod tests { ConditionResolution::Satisfied { cost: 0.0, path_tree: None, + context_map: None, } } diff --git a/apollo-federation/src/query_plan/display.rs b/apollo-federation/src/query_plan/display.rs index b6416590e1..48e9168684 100644 --- a/apollo-federation/src/query_plan/display.rs +++ b/apollo-federation/src/query_plan/display.rs @@ -377,6 +377,7 @@ impl fmt::Display for FetchDataPathElement { write_conditions(conditions, f) } Self::TypenameEquals(name) => write!(f, "... on {name}"), + Self::Parent => write!(f, ".."), } } } diff --git a/apollo-federation/src/query_plan/fetch_dependency_graph.rs b/apollo-federation/src/query_plan/fetch_dependency_graph.rs index ffffcba928..4a2da90e95 100644 --- a/apollo-federation/src/query_plan/fetch_dependency_graph.rs +++ b/apollo-federation/src/query_plan/fetch_dependency_graph.rs @@ -9,7 +9,6 @@ use apollo_compiler::ast::Argument; use apollo_compiler::ast::Directive; use apollo_compiler::ast::OperationType; use apollo_compiler::ast::Type; -use apollo_compiler::collections::HashMap; use apollo_compiler::collections::IndexMap; use apollo_compiler::collections::IndexSet; use apollo_compiler::executable; @@ -28,6 +27,8 @@ use petgraph::visit::IntoNodeReferences; use serde::Serialize; use super::query_planner::SubgraphOperationCompression; +use super::FetchDataKeyRenamer; +use crate::bail; use crate::display_helpers::DisplayOption; use crate::error::FederationError; use crate::error::SingleFederationError; @@ -86,7 +87,7 @@ type DeferRef = String; /// Like a multimap with a Set instead of a Vec for value storage. #[derive(Debug, Clone, Default)] struct DeferredNodes { - inner: HashMap>>, + inner: IndexMap>>, } impl DeferredNodes { fn new() -> Self { @@ -167,6 +168,8 @@ pub(crate) struct FetchDependencyGraphNode { inputs: Option>, /// Input rewrites for query plan execution to perform prior to executing the fetch. input_rewrites: Arc>>, + /// Rewrites that will need to occur to store contextual data for future use + context_inputs: Vec, /// As query plan execution runs, it accumulates fetch data into a response object. This is the /// path at which to merge in the data for this particular fetch. merge_at: Option>, @@ -225,6 +228,8 @@ pub(crate) struct FetchInputs { /// The supergraph schema (primarily used for validation of added selection sets). #[serde(skip)] supergraph_schema: ValidFederationSchema, + /// Contexts used as inputs + used_contexts: IndexMap>, } /// Represents a dependency between two subgraph fetches, namely that the tail/child depends on the @@ -791,6 +796,7 @@ impl FetchDependencyGraph { cached_cost: None, must_preserve_selection_set: false, is_known_useful: false, + context_inputs: Vec::new(), }))) } @@ -2343,11 +2349,11 @@ impl FetchDependencyGraph { &parent.selection_set.selection_set.schema, parent_op_path, )?; - let new_node_is_unneeded = node + let node_is_unneeded = node .selection_set .selection_set .can_rebase_on(&type_at_path, &parent.selection_set.selection_set.schema)?; - Ok(new_node_is_unneeded) + Ok(node_is_unneeded) } fn type_at_path( @@ -2510,6 +2516,14 @@ impl FetchDependencyGraphNode { Ok(()) } + fn add_input_context(&mut self, context: Name, ty: Node) -> Result<(), FederationError> { + let Some(inputs) = &mut self.inputs else { + bail!("Shouldn't try to add inputs to a root fetch node") + }; + Arc::make_mut(inputs).add_context(context, ty); + Ok(()) + } + fn copy_inputs(&mut self, other: &FetchDependencyGraphNode) -> Result<(), FederationError> { if let Some(other_inputs) = other.inputs.clone() { let inputs = self.inputs.get_or_insert_with(|| { @@ -2522,6 +2536,10 @@ impl FetchDependencyGraphNode { for rewrite in other.input_rewrites.iter() { input_rewrites.push(rewrite.clone()); } + + for context_input in &other.context_inputs { + self.add_context_renamer(context_input.clone()); + } } Ok(()) } @@ -2581,14 +2599,29 @@ impl FetchDependencyGraphNode { if self.selection_set.selection_set.selections.is_empty() { return Ok(None); } + let context_variable_definitions = self.inputs.iter().flat_map(|inputs| { + inputs.used_contexts.iter().map(|(context, ty)| { + Node::new(VariableDefinition { + name: context.clone(), + ty: ty.clone(), + default_value: None, + directives: Default::default(), + }) + }) + }); + let variable_definitions = variable_definitions + .iter() + .cloned() + .chain(context_variable_definitions) + .collect::>(); let (selection, output_rewrites) = - self.finalize_selection(variable_definitions, handled_conditions)?; + self.finalize_selection(&variable_definitions, handled_conditions)?; let input_nodes = self .inputs .as_ref() .map(|inputs| { inputs.to_selection_set_nodes( - variable_definitions, + &variable_definitions, handled_conditions, &self.parent_type, ) @@ -2694,7 +2727,12 @@ impl FetchDependencyGraphNode { operation_kind: self.root_kind.into(), input_rewrites: self.input_rewrites.clone(), output_rewrites, - context_rewrites: Default::default(), + context_rewrites: self + .context_inputs + .iter() + .cloned() + .map(|r| Arc::new(r.into())) + .collect(), })); Ok(Some(if let Some(path) = self.merge_at.clone() { @@ -2909,6 +2947,86 @@ impl FetchDependencyGraphNode { }; Some(format!("{subgraph_name}-{merge_at_str}")) } + + fn add_context_renamer(&mut self, renamer: FetchDataKeyRenamer) { + if !self.context_inputs.iter().any(|c| *c == renamer) { + self.context_inputs.push(renamer); + } + } + + fn add_context_renamers_for_selection_set( + &mut self, + selection_set: Option<&SelectionSet>, + relative_path: Vec, + alias: Name, + ) -> Result<(), FederationError> { + let selection_set = match selection_set { + Some(selection_set) if !selection_set.is_empty() => selection_set, + _ => { + self.add_context_renamer(FetchDataKeyRenamer { + path: relative_path, + rename_key_to: alias, + }); + return Ok(()); + } + }; + + for selection in selection_set { + match selection { + Selection::Field(field_selection) => { + if matches!(relative_path.last(), Some(FetchDataPathElement::Parent)) + && selection_set.type_position.type_name() != "Query" + { + for possible_runtime_type in selection_set + .schema + .possible_runtime_types(selection_set.type_position.clone())? + { + let mut new_relative_path = relative_path.clone(); + new_relative_path.push(FetchDataPathElement::TypenameEquals( + possible_runtime_type.type_name.clone(), + )); + self.add_context_renamers_for_selection_set( + Some(selection_set), + new_relative_path, + alias.clone(), + )?; + } + } else { + let mut new_relative_path = relative_path.clone(); + new_relative_path.push(FetchDataPathElement::Key( + field_selection.field.field_position.field_name().clone(), + Default::default(), + )); + self.add_context_renamers_for_selection_set( + field_selection.selection_set.as_ref(), + new_relative_path, + alias.clone(), + )?; + } + } + Selection::FragmentSpread(_) => { + bail!("Contexts shouldn't contain named fragment spreads"); + } + Selection::InlineFragment(inline_fragment_selection) => { + if let Some(type_condition) = &inline_fragment_selection + .inline_fragment + .type_condition_position + { + let mut new_relative_path = relative_path.clone(); + new_relative_path.push(FetchDataPathElement::TypenameEquals( + type_condition.type_name().clone(), + )); + self.add_context_renamers_for_selection_set( + Some(&inline_fragment_selection.selection_set), + new_relative_path, + alias.clone(), + )?; + } + } + } + } + Ok(()) + } } fn operation_for_entities_fetch( @@ -3093,6 +3211,7 @@ impl FetchInputs { Self { selection_sets_per_parent_type: Default::default(), supergraph_schema, + used_contexts: Default::default(), } } @@ -3118,7 +3237,12 @@ impl FetchInputs { other .selection_sets_per_parent_type .values() - .try_for_each(|selections| self.add(selections)) + .try_for_each(|selections| self.add(selections))?; + other + .used_contexts + .iter() + .for_each(|(context, ty)| self.add_context(context.clone(), ty.clone())); + Ok(()) } fn contains(&self, other: &Self) -> bool { @@ -3130,7 +3254,13 @@ impl FetchInputs { return false; } } - true + if self.used_contexts.len() < other.used_contexts.len() { + return false; + } + other + .used_contexts + .keys() + .all(|context| self.used_contexts.contains_key(context)) } fn equals(&self, other: &Self) -> bool { @@ -3153,8 +3283,13 @@ impl FetchInputs { } // so far so good } - // all clear - true + if self.used_contexts.len() != other.used_contexts.len() { + return false; + } + other + .used_contexts + .keys() + .all(|context| self.used_contexts.contains_key(context)) } fn to_selection_set_nodes( @@ -3177,6 +3312,10 @@ impl FetchInputs { selections: Arc::new(selections), }) } + + fn add_context(&mut self, context: Name, ty: Node) { + self.used_contexts.insert(context, ty); + } } impl std::fmt::Display for FetchInputs { @@ -3335,6 +3474,7 @@ struct ComputeNodesStackItem<'a> { node_path: FetchDependencyGraphNodePath, context: &'a OpGraphPathContext, defer_context: DeferContext, + context_to_condition_nodes: Arc>>, } #[cfg_attr( @@ -3356,6 +3496,7 @@ pub(crate) fn compute_nodes_for_tree( node_path: initial_node_path, context: initial_conditions, defer_context: initial_defer_context, + context_to_condition_nodes: Arc::new(Default::default()), }]; let mut created_nodes = IndexSet::default(); while let Some(stack_item) = stack.pop() { @@ -3595,6 +3736,7 @@ fn compute_nodes_for_key_resolution<'a>( )?), context: new_context, defer_context: updated_defer_context, + context_to_condition_nodes: stack_item.context_to_condition_nodes.clone(), }) } @@ -3696,6 +3838,7 @@ fn compute_nodes_for_root_type_resolution<'a>( context: new_context, defer_context: updated_defer_context, + context_to_condition_nodes: stack_item.context_to_condition_nodes.clone(), }) } @@ -3735,11 +3878,13 @@ fn compute_nodes_for_op_path_element<'a>( }, context: stack_item.context, defer_context: updated_defer_context, + context_to_condition_nodes: stack_item.context_to_condition_nodes.clone(), }); }; let (source_id, dest_id) = stack_item.tree.graph.edge_endpoints(edge_id)?; let source = stack_item.tree.graph.node_weight(source_id)?; let dest = stack_item.tree.graph.node_weight(dest_id)?; + let edge = stack_item.tree.graph.edge_weight(edge_id)?; if source.source != dest.source { return Err(FederationError::internal(format!( "Collecting edge {edge_id:?} for {operation_element:?} \ @@ -3793,21 +3938,227 @@ fn compute_nodes_for_op_path_element<'a>( node_path: stack_item.node_path.clone(), context: stack_item.context, defer_context: updated_defer_context, + context_to_condition_nodes: stack_item.context_to_condition_nodes.clone(), }; if let Some(conditions) = &child.conditions { // We have @requires or some other dependency to create nodes for. - let (required_node_id, require_path) = handle_requires( + let conditions_node_data = handle_conditions_tree( dependency_graph, - edge_id, conditions, (stack_item.node_id, &stack_item.node_path), - stack_item.context, + // If setting a context, add __typename to the site where we are retrieving context from + // since the context rewrites path will start with a type condition. + if child.context_to_selection.is_some() { + Some(edge_id) + } else { + None + }, &updated.defer_context, created_nodes, )?; - updated.node_id = required_node_id; - updated.node_path = require_path; + + if let Some(context_to_selection) = &child.context_to_selection { + let mut condition_nodes = vec![conditions_node_data.conditions_merge_node_id]; + condition_nodes.extend(&conditions_node_data.created_node_ids); + let mut context_to_condition_nodes = + stack_item.context_to_condition_nodes.deref().clone(); + for context in context_to_selection { + context_to_condition_nodes.insert(context.clone(), condition_nodes.clone()); + } + updated.context_to_condition_nodes = Arc::new(context_to_condition_nodes); + } + + if edge.conditions.is_some() { + // This edge needs the conditions just fetched, to be provided via _entities (@requires + // or fake interface object downcast). So we create the post-@requires group, adding the + // subgraph jump (if it isn't optimized away). + let (required_node_id, require_path) = create_post_requires_node( + dependency_graph, + edge_id, + (stack_item.node_id, &stack_item.node_path), + stack_item.context, + conditions_node_data, + created_nodes, + )?; + updated.node_id = required_node_id; + updated.node_path = require_path; + } + } + + // If the edge uses context variables, every context used must be set in a different parent + // node or else we need to create a new one. + if let Some(parameter_to_context) = &child.parameter_to_context { + let mut conditions_nodes: IndexSet = Default::default(); + let mut is_subgraph_jump_needed = false; + for context_entry in parameter_to_context.values() { + let Some(context_nodes) = updated + .context_to_condition_nodes + .get(&context_entry.context_id) + else { + bail!( + "Could not find condition nodes for context {}", + context_entry.context_id + ); + }; + conditions_nodes.extend(context_nodes); + if context_nodes + .first() + .is_some_and(|node_id| *node_id == updated.node_id) + { + is_subgraph_jump_needed = true; + } + } + if is_subgraph_jump_needed { + if updated.node_id != stack_item.node_id { + bail!("Node created by post-@requires handling shouldn't have set context already"); + } + + let source_type: CompositeTypeDefinitionPosition = source.type_.clone().try_into()?; + let source_schema: ValidFederationSchema = dependency_graph + .federated_query_graph + .schema_by_source(&source.source)? + .clone(); + let path_in_parent = &stack_item.node_path.path_in_node; + // NOTE: We should re-examine defer-handling for path elements in this function in the + // future to ensure they're working as intended. + let new_node_id = dependency_graph.get_or_create_key_node( + &source.source, + &stack_item.node_path.response_path, + &source_type, + ParentRelation { + parent_node_id: stack_item.node_id, + path_in_parent: Some(Arc::clone(path_in_parent)), + }, + &conditions_nodes, + None, + )?; + created_nodes.insert(new_node_id); + updated.node_id = new_node_id; + updated.node_path = stack_item + .node_path + .for_new_key_fetch(create_fetch_initial_path( + &dependency_graph.supergraph_schema, + &source_type, + stack_item.context, + )?); + + let Some(key_condition) = stack_item + .tree + .graph + .get_locally_satisfiable_key(source_id)? + else { + bail!( + "can_satisfy_conditions() validation should have required a key to be present for edge {}", + edge, + ) + }; + let mut key_inputs = + SelectionSet::for_composite_type(source_schema.clone(), source_type.clone()); + key_inputs.add_selection_set(&key_condition)?; + let node = FetchDependencyGraph::node_weight_mut( + &mut dependency_graph.graph, + stack_item.node_id, + )?; + node.selection_set + .add_at_path(path_in_parent, Some(&Arc::new(key_inputs)))?; + + let Ok(input_type): Result = dependency_graph + .supergraph_schema + .get_type(source_type.type_name().clone())? + .try_into() + else { + bail!( + "Type {} should exist in the supergraph and be a composite type", + source_type.type_name() + ); + }; + let mut input_selection_set = SelectionSet::for_composite_type( + dependency_graph.supergraph_schema.clone(), + input_type.clone(), + ); + input_selection_set.add_selection_set(&key_condition)?; + let inputs = wrap_input_selections( + &dependency_graph.supergraph_schema, + &input_type, + input_selection_set, + stack_item.context, + ); + let input_rewrites = compute_input_rewrites_on_key_fetch( + source_type.type_name(), + &source_type, + &source_schema, + )?; + let updated_node = FetchDependencyGraph::node_weight_mut( + &mut dependency_graph.graph, + updated.node_id, + )?; + updated_node.add_inputs(&inputs, input_rewrites.into_iter().flatten())?; + + // Add the condition nodes as parent nodes. + for parent_node_id in conditions_nodes { + dependency_graph.add_parent( + updated.node_id, + ParentRelation { + parent_node_id, + path_in_parent: None, + }, + ); + } + + // Add context renamers. + for context_entry in parameter_to_context.values() { + let updated_node = FetchDependencyGraph::node_weight_mut( + &mut dependency_graph.graph, + updated.node_id, + )?; + updated_node.add_input_context( + context_entry.context_id.clone(), + context_entry.subgraph_arg_type.clone(), + )?; + updated_node.add_context_renamers_for_selection_set( + Some(&context_entry.selection_set), + context_entry.relative_path.clone(), + context_entry.context_id.clone(), + )?; + } + } else { + // In this case we can just continue with the current node, but we need to add the + // condition nodes as parents and the context renamers. + for parent_node_id in conditions_nodes { + dependency_graph.add_parent( + updated.node_id, + ParentRelation { + parent_node_id, + path_in_parent: None, + }, + ); + } + let num_fields = updated + .node_path + .path_in_node + .iter() + .filter(|e| matches!((**e).deref(), OpPathElement::Field(_))) + .count(); + for context_entry in parameter_to_context.values() { + let new_relative_path = &context_entry.relative_path + [..(context_entry.relative_path.len() - num_fields)]; + let updated_node = FetchDependencyGraph::node_weight_mut( + &mut dependency_graph.graph, + updated.node_id, + )?; + updated_node.add_input_context( + context_entry.context_id.clone(), + context_entry.subgraph_arg_type.clone(), + )?; + updated_node.add_context_renamers_for_selection_set( + Some(&context_entry.selection_set), + new_relative_path.to_vec(), + context_entry.context_id.clone(), + )?; + } + } } + if let OpPathElement::Field(field) = &updated_operation { if *field.name() == TYPENAME_FIELD { // Because of the optimization done in `QueryPlanner.optimizeSiblingTypenames`, @@ -3850,7 +4201,6 @@ fn compute_nodes_for_op_path_element<'a>( updated_node.must_preserve_selection_set = true } } - let edge = child.tree.graph.edge_weight(edge_id)?; if let QueryGraphEdgeTransition::InterfaceObjectFakeDownCast { .. } = &edge.transition { // We shouldn't add the operation "as is" as it's a down-cast but we're "faking it". // However, if the operation has directives, we should preserve that. @@ -4064,134 +4414,183 @@ fn extract_defer_from_operation( Ok((updated_operation_element, updated_context)) } -fn handle_requires( +struct ConditionsNodeData { + conditions_merge_node_id: NodeIndex, + path_in_conditions_merge_node_id: Option>, + created_node_ids: Vec, + is_fully_local_requires: bool, +} + +/// Computes nodes for conditions imposed by @requires, @fromContext, and @interfaceObject, merging +/// them into ancestors as an optimization if possible. This does not modify the current node to +/// use the condition data as input, nor does it create parent-child relationships with created +/// nodes and the current node. +fn handle_conditions_tree( dependency_graph: &mut FetchDependencyGraph, - query_graph_edge_id: EdgeIndex, - requires_conditions: &OpPathTree, + conditions: &OpPathTree, (fetch_node_id, fetch_node_path): (NodeIndex, &FetchDependencyGraphNodePath), - context: &OpGraphPathContext, + query_graph_edge_id_if_typename_needed: Option, defer_context: &DeferContext, created_nodes: &mut IndexSet, -) -> Result<(NodeIndex, FetchDependencyGraphNodePath), FederationError> { - // @requires should be on an entity type, and we only support object types right now - let head = dependency_graph - .federated_query_graph - .edge_head_weight(query_graph_edge_id)?; - let entity_type_schema = dependency_graph - .federated_query_graph - .schema_by_source(&head.source)? - .clone(); - let QueryGraphNodeType::SchemaType(OutputTypeDefinitionPosition::Object(entity_type_position)) = - head.type_.clone() - else { - return Err(FederationError::internal( - "@requires applied on non-entity object type", - )); - }; - - // In many cases, we can optimize @requires by merging the requirement to previously existing nodes. However, - // we only do this when the current node has only a single parent (it's hard to reason about it otherwise). - // But the current node could have multiple parents due to the graph lacking minimality, and we don't want that - // to needlessly prevent us from this optimization. So we do a graph reduction first (which effectively - // just eliminate unnecessary edges). To illustrate, we could be in a case like: +) -> Result { + // In many cases, we can optimize conditions by merging the fields into previously existing + // nodes. However, we only do this when the current node has only a single parent (it's hard to + // reason about it otherwise). But the current node could have multiple parents due to the graph + // lacking minimality, and we don't want that to needlessly prevent us from this optimization. + // So we do a graph reduction first (which effectively just eliminates unnecessary edges). To + // illustrate, we could be in a case like: // 1 // / \ // 0 --- 2 - // with current node 2. And while the node currently has 2 parents, the `reduce` step will ensure - // the edge `0 --- 2` is removed (since the dependency of 2 on 0 is already provide transitively through 1). + // with current node 2. And while the node currently has 2 parents, the `reduce` step will + // ensure the edge `0 --- 2` is removed (since the dependency of 2 on 0 is already provided + // transitively through 1). dependency_graph.reduce(); - let single_parent = iter_into_single_item(dependency_graph.parents_relations_of(fetch_node_id)); - // In general, we should do like for an edge, and create a new node _for the current subgraph_ - // that depends on the created_nodes and have the created nodes depend on the current one. - // However, we can be more efficient in general (and this is expected by the user) because - // required fields will usually come just after a key edge (at the top of a fetch node). - // In that case (when the path is only type_casts), we can put the created nodes directly - // as dependency of the current node, avoiding creation of a new one. Additionally, if the + // In general, we should do like for a key edge, and create a new node _for the current + // subgraph_ that depends on the created nodes and have the created nodes depend on the current + // one. However, we can be more efficient in general (and this is expected by the user) because + // condition fields will usually come just after a key edge (at the top of a fetch node). + // In that case (when the path is only type conditions), we can put the created nodes directly + // as dependencies of the current node, avoiding creation of a new one. Additionally, if the // node we're coming from is our "direct parent", we can merge it to said direct parent (which - // effectively means that the parent node will collect the provides before taking the edge - // to our current node). - if single_parent.is_some() && fetch_node_path.path_in_node.has_only_fragments() { - // Should do `if let` but it requires extra indentation. - let parent = single_parent.unwrap(); - - // We start by computing the nodes for the conditions. We do this using a copy of the current - // node (with only the inputs) as that allows to modify this copy without modifying `node`. - let fetch_node = dependency_graph.node_weight(fetch_node_id)?; - let subgraph_name = fetch_node.subgraph_name.clone(); - let Some(merge_at) = fetch_node.merge_at.clone() else { - return Err(FederationError::internal(format!( - "Fetch node {} merge_at_path is required but was missing", - fetch_node_id.index() - ))); + // effectively means that the parent node will collect subgraph-local condition fields before + // taking the edge to our current node). + let copied_node_id_and_parent = + match iter_into_single_item(dependency_graph.parents_relations_of(fetch_node_id)) { + Some(parent) if fetch_node_path.path_in_node.has_only_fragments() => { + // Since we may want the condition fields in this case to be added into an earlier + // node, we create a copy of the current node (with only the inputs), and the + // condition fields will be added to this node instead of the current one. + let fetch_node = dependency_graph.node_weight(fetch_node_id)?; + let subgraph_name = fetch_node.subgraph_name.clone(); + let Some(merge_at) = fetch_node.merge_at.clone() else { + bail!( + "Fetch node {} merge_at_path is required but was missing", + fetch_node_id.index() + ); + }; + let defer_ref = fetch_node.defer_ref.clone(); + let copied_node_id = + dependency_graph.new_key_node(&subgraph_name, merge_at, defer_ref.clone())?; + dependency_graph.add_parent(copied_node_id, parent.clone()); + dependency_graph.copy_inputs(copied_node_id, fetch_node_id)?; + Some((copied_node_id, parent)) + } + _ => None, }; - let defer_ref = fetch_node.defer_ref.clone(); - let new_node_id = - dependency_graph.new_key_node(&subgraph_name, merge_at, defer_ref.clone())?; - dependency_graph.add_parent(new_node_id, parent.clone()); - dependency_graph.copy_inputs(new_node_id, fetch_node_id)?; - let newly_created_node_ids = compute_nodes_for_tree( - dependency_graph, - requires_conditions, - new_node_id, - fetch_node_path.clone(), - defer_context.for_conditions(), - &OpGraphPathContext::default(), - )?; - if newly_created_node_ids.is_empty() { - // All conditions were local. Just merge the newly created node back into the current node (we didn't need it) - // and continue. - if !dependency_graph.can_merge_sibling_in(fetch_node_id, new_node_id)? { - return Err(FederationError::internal(format!( + let condition_node_id = match &copied_node_id_and_parent { + Some((copied_node_id, _)) => *copied_node_id, + None => fetch_node_id, + }; + if let Some(query_graph_edge_id) = query_graph_edge_id_if_typename_needed { + let head = dependency_graph + .federated_query_graph + .edge_head_weight(query_graph_edge_id)?; + let head_type: CompositeTypeDefinitionPosition = head.type_.clone().try_into()?; + let head_schema = dependency_graph + .federated_query_graph + .schema_by_source(&head.source)? + .clone(); + let typename_field = Arc::new(OpPathElement::Field(Field::new_introspection_typename( + &head_schema, + &head_type, + None, + ))); + let typename_path = fetch_node_path.path_in_node.with_pushed(typename_field); + let condition_node = + FetchDependencyGraph::node_weight_mut(&mut dependency_graph.graph, condition_node_id)?; + condition_node + .selection_set_mut() + .add_at_path(&typename_path, None)?; + } + + // Compute the node changes/additions introduced by the conditions path tree, using either the + // current node or the copy of the current node if we expect to optimize. + let newly_created_node_ids = compute_nodes_for_tree( + dependency_graph, + conditions, + condition_node_id, + fetch_node_path.clone(), + defer_context.for_conditions(), + &OpGraphPathContext::default(), + )?; + + if newly_created_node_ids.is_empty() { + // All conditions were local. If we copied the node expecting to optimize, just merge it + // back into the current node (we didn't need it) and continue. + // + // NOTE: This behavior is largely to maintain backwards compatibility with @requires. For + // @fromContext, it still may be useful to merge the conditions into the parent if possible. + // but we leave this optimization for later. + if let Some((copied_node_id, _)) = copied_node_id_and_parent { + if !dependency_graph.can_merge_sibling_in(fetch_node_id, copied_node_id)? { + bail!( "We should be able to merge {} into {} by construction", - new_node_id.index(), + copied_node_id.index(), fetch_node_id.index() - ))); + ); } - dependency_graph.merge_sibling_in(fetch_node_id, new_node_id)?; - return Ok((fetch_node_id, fetch_node_path.clone())); + dependency_graph.merge_sibling_in(fetch_node_id, copied_node_id)?; } + return Ok(ConditionsNodeData { + conditions_merge_node_id: fetch_node_id, + path_in_conditions_merge_node_id: Some(Arc::new(Default::default())), + created_node_ids: vec![], + is_fully_local_requires: true, + }); + } - // We know the @requires needs `newly_created_node_ids`. We do want to know however if any of the conditions was - // fetched from our `new_node`. If not, then this means that the `newly_created_node_ids` don't really depend on - // the current `node` and can be dependencies of the parent (or even merged into this parent). + if let Some((copied_node_id, parent)) = copied_node_id_and_parent { + // We know the conditions depend on at least one created node. We do want to know, however, + // if any of the condition fields was fetched from our copied node. If not, then this means + // that the created nodes don't really depend on the current node and can be dependencies + // of the parent (or even merged into the parent). // - // So we want to know if anything in `new_node` selection cannot be fetched directly from the parent. - // For that, we first remove any of `new_node` inputs from its selection: in most case, `new_node` - // will just contain the key needed to jump back to its parent, and those would usually be the same - // as the inputs. And since by definition we know `new_node`'s inputs are already fetched, we - // know they are not things that we need. Then, we check if what remains (often empty) can be - // directly fetched from the parent. If it can, then we can just merge `new_node` into that parent. - // Otherwise, we will have to "keep it". - // Note: it is to be sure this test is not polluted by other things in `node` that we created `new_node`. - dependency_graph.remove_inputs_from_selection(new_node_id)?; - - let new_node_is_not_needed = dependency_graph.is_node_unneeded(new_node_id, &parent)?; + // So we want to know if anything in the copied node's selections cannot be fetched directly + // from the parent. For that, we first remove any of the copied node's inputs from its + // selections: in most cases, the copied node will just contain the key needed to jump back + // to its parent, and those would usually be the same as its inputs. And since by definition + // we know copied node's inputs are already fetched, we know they are not things that we + // need. Then, we check if what remains (often empty) can be directly fetched from the + // parent. If it can, then we can just merge the copied node into that parent. Otherwise, we + // will have to "keep it". + // + // NOTE: We have explicitly copied the current node without its selections, so the current + // node's fields should not pollute this check on the copied node. + dependency_graph.remove_inputs_from_selection(copied_node_id)?; + let copied_node_is_unneeded = dependency_graph.is_node_unneeded(copied_node_id, &parent)?; let mut unmerged_node_ids: Vec = Vec::new(); - if new_node_is_not_needed { - // Up to this point, `new_node` had no parent, so let's first merge `new_node` to the parent, thus "rooting" - // its children to it. Note that we just checked that `new_node` selection was just its inputs, so - // we know that merging it to the parent is mostly a no-op from that POV, except maybe for requesting - // a few additional `__typename` we didn't before (due to the exclusion of `__typename` in the `new_node_is_unneeded` check) - dependency_graph.merge_child_in(parent.parent_node_id, new_node_id)?; - - // Now, all created groups are going to be descendant of `parentGroup`. But some of them may actually be - // mergeable into it. + if copied_node_is_unneeded { + // We've removed the copied node's inputs from its own selections, and confirmed the + // remaining fields can be fetched from the parent. As an optimization, we now merge it + // into the parent, thus "rooting" the copied node's children to that parent. Note that + // the copied node's selections are often empty after removing inputs, so merging it + // into the parent is usually a no-op from that POV, except maybe for requesting + // a few additional `__typename`s we didn't before. + dependency_graph.merge_child_in(parent.parent_node_id, copied_node_id)?; + + // Now, all created nodes are going to be descendants of the parent node. But some of + // them may actually be mergeable into it. for created_node_id in newly_created_node_ids { - // Note that `created_node_id` may not be a direct child of `parent_node_id`, but `can_merge_child_in` just return `false` in - // that case, yielding the behaviour we want (not trying to merge it in). + // Note that `created_node_id` may not be a direct child of `parent_node_id`, but + // `can_merge_child_in()` just returns `false` in that case, yielding the behavior + // we want (not trying to merge it in). if dependency_graph.can_merge_child_in(parent.parent_node_id, created_node_id)? { dependency_graph.merge_child_in(parent.parent_node_id, created_node_id)?; } else { unmerged_node_ids.push(created_node_id); - // `created_node_id` cannot be merged into `parent_node_id`, which may typically be because they are not to the same - // subgraph. However, while `created_node_id` currently depend on `parent_node_id` (directly or indirectly), that - // dependency just come from the fact that `parent_node_id` is the parent of the node whose @requires we're - // dealing with. And in practice, it could well be that some of the fetches needed for that require don't - // really depend on anything that parent fetches and could be done in parallel with it. If we detect that - // this is the case for `created_node_id`, we can move it "up the chain of dependency". + // `created_node_id` cannot be merged into `parent_node_id`, which may typically + // be because they aren't to the same subgraph. However, while `created_node_id` + // currently depends on `parent_node_id` (directly or indirectly), that + // dependency just comes from the fact that `parent_node_id` is the parent of + // the node whose conditions we're dealing with. And in practice, it could well + // be that some of the fetches needed for those conditions don't really depend + // on anything that the parent fetches and could be done in parallel with it. If + // we detect that this is the case for `created_node_id`, we can move it "up the + // chain of dependencies". let mut current_parent = parent.clone(); while dependency_graph.is_child_of_with_artificial_dependency( created_node_id, @@ -4204,10 +4603,10 @@ fn handle_requires( .parents_relations_of(current_parent.parent_node_id) .collect(); if grand_parents.is_empty() { - return Err(FederationError::internal(format!( + bail!( "Fetch node {} is not top-level, so it should have parents", current_parent.parent_node_id.index() - ))); + ); } for grand_parent_relation in &grand_parents { dependency_graph.add_parent( @@ -4233,26 +4632,26 @@ fn handle_requires( } } } else { - // We cannot merge `new_node_id` to the parent, either because there it fetches some things necessary to the - // @requires, or because we had more than one parent and don't know how to handle this (unsure if the later - // can actually happen at this point tbh (?)). But there is no reason not to merge `new_node_id` back to `fetch_node_id` - // so we do that first. - if !dependency_graph.can_merge_sibling_in(fetch_node_id, new_node_id)? { - return Err(FederationError::internal(format!( + // We cannot merge the copied node into the parent because it fetches some conditions + // fields that can't be fetched from the parent. We bail on this specific optimization, + // and accordingly merge the copied node back to the original current node. + if !dependency_graph.can_merge_sibling_in(fetch_node_id, copied_node_id)? { + bail!( "We should be able to merge {} into {} by construction", - new_node_id.index(), + copied_node_id.index(), fetch_node_id.index() - ))); + ); }; - dependency_graph.merge_sibling_in(fetch_node_id, new_node_id)?; - - // The created node depend on `fetch_node` and the dependency cannot be moved to the parent in - // this case. However, we might still be able to merge some created nodes directly in the - // parent. But for this to be true, we should essentially make sure that the dependency - // on `node` is not a "true" dependency. That is, if the created node inputs are the same - // as `node` inputs (and said created node is the same subgraph as the parent of - // `node`, then it means we depend only on values that are already in the parent and - // can merge the node). + dependency_graph.merge_sibling_in(fetch_node_id, copied_node_id)?; + + // The created nodes depend on the current node, and the dependency cannot be moved to + // the parent in this case. However, we might still be able to merge some created nodes + // directly into the parent. But for this to be true, we should essentially make sure + // that the dependency on the current node is not a "true" dependency. That is, if a + // created node's inputs are the same as the current node's inputs (and said created + // node is the same subgraph as the parent of the current node), then it means we depend + // only on values that are already fetched by the parent and/or its ancestors, and + // can merge that created node into the parent. if parent.path_in_parent.is_some() { for created_node_id in newly_created_node_ids { if dependency_graph.can_merge_grand_child_in( @@ -4269,11 +4668,84 @@ fn handle_requires( } } - // If we've merged all the created nodes, then all the "requires" are handled _before_ we get to the - // current node, so we can "continue" with the current node. - if unmerged_node_ids.is_empty() { - // We still need to add the stuffs we require though (but `node` already has a key in its inputs, - // we don't need one). + created_nodes.extend(unmerged_node_ids.clone()); + Ok(ConditionsNodeData { + conditions_merge_node_id: if copied_node_is_unneeded { + parent.parent_node_id + } else { + fetch_node_id + }, + path_in_conditions_merge_node_id: if copied_node_is_unneeded { + parent.path_in_parent + } else { + Some(Arc::new(Default::default())) + }, + created_node_ids: unmerged_node_ids, + is_fully_local_requires: false, + }) + } else { + // We're in the somewhat simpler case where the conditions are queried somewhere in the + // middle of a subgraph fetch (so, not just after having jumped to that subgraph), or + // there's more than one parent. In that case, there isn't much optimisation we can easily + // do, so we leave the nodes as-is. + created_nodes.extend(newly_created_node_ids.clone()); + Ok(ConditionsNodeData { + conditions_merge_node_id: fetch_node_id, + path_in_conditions_merge_node_id: Some(Arc::new(Default::default())), + created_node_ids: newly_created_node_ids.into_iter().collect(), + is_fully_local_requires: false, + }) + } +} + +/// Adds a @requires edge into the node at the given path, instead making a new node if optimization +/// cannot place that edge in the given node. This function assumes handle_conditions_tree() has +/// already been called, and accordingly takes its outputs. +fn create_post_requires_node( + dependency_graph: &mut FetchDependencyGraph, + query_graph_edge_id: EdgeIndex, + (fetch_node_id, fetch_node_path): (NodeIndex, &FetchDependencyGraphNodePath), + context: &OpGraphPathContext, + conditions_node_data: ConditionsNodeData, + created_nodes: &mut IndexSet, +) -> Result<(NodeIndex, FetchDependencyGraphNodePath), FederationError> { + // @requires should be on an entity type, and we only support object types right now. + let head = dependency_graph + .federated_query_graph + .edge_head_weight(query_graph_edge_id)?; + let entity_type_schema = dependency_graph + .federated_query_graph + .schema_by_source(&head.source)? + .clone(); + let QueryGraphNodeType::SchemaType(OutputTypeDefinitionPosition::Object(entity_type_position)) = + head.type_.clone() + else { + bail!("@requires applied on non-entity object type"); + }; + + // If all required fields could be fetched locally, we "continue" with the current node. + if conditions_node_data.is_fully_local_requires { + return Ok((fetch_node_id, fetch_node_path.clone())); + } + + // NOTE: The code paths diverge below similar to handle_conditions_tree(), checking whether we + // tried optimizing based on whether there's a single parent and whether the path in the node is + // only type conditions. This is largely meant to just keep behavior the same as before and be + // aligned with the JS query planner. This could change in the future though, to permit simpler + // handling and further optimization. (There's also some arguably buggy behavior in this + // function we ought to resolve in the future.) + let parent_if_tried_optimizing = + match iter_into_single_item(dependency_graph.parents_relations_of(fetch_node_id)) { + Some(parent) if fetch_node_path.path_in_node.has_only_fragments() => Some(parent), + _ => None, + }; + + if let Some(parent) = parent_if_tried_optimizing { + // If all created nodes were merged into ancestors, then those nodes' data are fetched + // _before_ we get to the current node, so we "continue" with the current node. + if conditions_node_data.created_node_ids.is_empty() { + // We still need to add the required fields as inputs to the current node (but the node + // should already have a key in its inputs, so we don't need to add that). let inputs = inputs_for_require( dependency_graph, entity_type_position.clone(), @@ -4289,51 +4761,51 @@ fn handle_requires( return Ok((fetch_node_id, fetch_node_path.clone())); } - // If we get here, it means that @require needs the information from `unmerged_nodes` (plus whatever has - // been merged before) _and_ those rely on some information from the current `fetch_node` (if they hadn't, we - // would have been able to merge `new_node` to `fetch_node`'s parent). So the group we should return, which - // is the node where the "post-@require" fields will be added, needs to be a new node that depends - // on all those `unmerged_nodes`. - let post_require_node_id = dependency_graph.new_key_node( - &subgraph_name, + // If we get here, it means that @requires needs the fields from the created nodes (plus + // potentially whatever has been merged before). So the node we should return, which is the + // node where the "post-@requires" fields will be given as input, needs to a be a new node + // that depends on all those created nodes. + let fetch_node = dependency_graph.node_weight(fetch_node_id)?; + let target_subgraph = fetch_node.subgraph_name.clone(); + let defer_ref = fetch_node.defer_ref.clone(); + let post_requires_node_id = dependency_graph.new_key_node( + &target_subgraph, fetch_node_path.response_path.clone(), defer_ref, )?; - // Note that `post_require_node` cannot generally be merged in any of the `unmerged_nodes` and we don't provide a `path`. - for unmerged_node_id in &unmerged_node_ids { + // Note that the post-requires node cannot generally be merged into any of the created + // nodes, and we accordingly don't provide a path in those created nodes. + for created_node_id in &conditions_node_data.created_node_ids { dependency_graph.add_parent( - post_require_node_id, + post_requires_node_id, ParentRelation { - parent_node_id: *unmerged_node_id, + parent_node_id: *created_node_id, path_in_parent: None, }, ); } - // That node also need, in general, to depend on the current `fetch_node`. That said, if we detected that the @require - // didn't need anything of said `node` (if `new_node_is_unneeded`), then we can depend on the parent instead. - if new_node_is_not_needed { - dependency_graph.add_parent(post_require_node_id, parent.clone()); - } else { - dependency_graph.add_parent( - post_require_node_id, - ParentRelation { - parent_node_id: fetch_node_id, - path_in_parent: Some(Arc::new(OpPath::default())), - }, - ) - } + // The post-requires node also needs to, in general, depend on the node that the @requires + // conditions were merged into (either the current node or its parent). + dependency_graph.add_parent( + post_requires_node_id, + ParentRelation { + parent_node_id: conditions_node_data.conditions_merge_node_id, + path_in_parent: conditions_node_data.path_in_conditions_merge_node_id, + }, + ); - // Note(Sylvain): I'm not 100% sure about this assert in the sense that while I cannot think of a case where `parent.path_in_parent` wouldn't - // exist, the code paths are complex enough that I'm not able to prove this easily and could easily be missing something. That said, - // we need the path here, so this will have to do for now, and if this ever breaks in practice, we'll at least have an example to - // guide us toward improving/fixing. + // NOTE(Sylvain): I'm not 100% sure about this assert in the sense that while I cannot think + // of a case where `parent.path_in_parent` wouldn't exist, the code paths are complex enough + // that I'm not able to prove this easily and could easily be missing something. That said, + // we need the path here, so this will have to do for now, and if this ever breaks in + // practice, we'll at least have an example to guide us toward improving/fixing the code. let Some(parent_path) = &parent.path_in_parent else { - return Err(FederationError::internal(format!( + bail!( "Missing path_in_parent for @require on {} with group {} and parent {}", query_graph_edge_id.index(), fetch_node_id.index(), parent.parent_node_id.index() - ))); + ); }; let path_for_parent = path_for_parent( dependency_graph, @@ -4349,61 +4821,43 @@ fn handle_requires( query_graph_edge_id, context, parent.parent_node_id, - post_require_node_id, + post_requires_node_id, )?; - created_nodes.extend(unmerged_node_ids); - created_nodes.insert(post_require_node_id); + created_nodes.insert(post_requires_node_id); let initial_fetch_path = create_fetch_initial_path( &dependency_graph.supergraph_schema, &entity_type_position.clone().into(), context, )?; let new_path = fetch_node_path.for_new_key_fetch(initial_fetch_path); - Ok((post_require_node_id, new_path)) + Ok((post_requires_node_id, new_path)) } else { - // We're in the somewhat simpler case where a @require happens somewhere in the middle of a subgraph query (so, not - // just after having jumped to that subgraph). In that case, there isn't tons of optimisation we can do: we have to - // see what satisfying the @require necessitate, and if it needs anything from another subgraph, we have to stop the - // current subgraph fetch there, get the requirements from other subgraphs, and then resume the query of that particular subgraph. - let new_created_nodes = compute_nodes_for_tree( - dependency_graph, - requires_conditions, - fetch_node_id, - fetch_node_path.clone(), - defer_context.for_conditions(), - &OpGraphPathContext::default(), - )?; - // If we didn't create any node, that means the whole condition was fetched from the current node - // and we're good. - if new_created_nodes.is_empty() { - return Ok((fetch_node_id, fetch_node_path.clone())); - } - - // We need to create a new name, on the same subgraph `group`, where we resume fetching the field for - // which we handle the @requires _after_ we've dealt with the `requires_conditions_nodes`. - // Note that we know the conditions will include a key for our node so we can resume properly. + // We need to create a new node on the same subgraph as the current node, where we resume + // fetching the field for which we handle the @requires _after_ we've dealt with any created + // nodes. Note that during option generation, we already ensured a key exists, so the node + // can resume properly. let fetch_node = dependency_graph.node_weight(fetch_node_id)?; let target_subgraph = fetch_node.subgraph_name.clone(); let defer_ref = fetch_node.defer_ref.clone(); - let new_node_id = dependency_graph.new_key_node( + let post_requires_node_id = dependency_graph.new_key_node( &target_subgraph, fetch_node_path.response_path.clone(), defer_ref, )?; - let new_node = dependency_graph.node_weight(new_node_id)?; - let merge_at = new_node.merge_at.clone(); - let parent_type = new_node.parent_type.clone(); - for created_node_id in &new_created_nodes { + let post_requires_node = dependency_graph.node_weight(post_requires_node_id)?; + let merge_at = post_requires_node.merge_at.clone(); + let parent_type = post_requires_node.parent_type.clone(); + for created_node_id in &conditions_node_data.created_node_ids { let created_node = dependency_graph.node_weight(*created_node_id)?; - // Usually, computing the path of our new group into the created groups - // is not entirely trivial, but there is at least the relatively common - // case where the 2 groups we look at have: - // 1) the same `mergeAt`, and - // 2) the same parentType; in that case, we can basically infer those 2 - // groups apply at the same "place" and so the "path in parent" is - // empty. TODO: it should probably be possible to generalize this by - // checking the `mergeAt` plus analyzing the selection but that - // warrants some reflection... + // Usually, computing the path of the post-requires node in the created nodes is not + // entirely trivial, but there is at least one relatively common case where the 2 nodes + // we look at have (1) the same merge-at, and (2) the same parent type. + // + // In that case, we can basically infer those 2 nodes apply at the same "place" and so + // the "path in parent" is empty. + // + // TODO(Sylvain): it should probably be possible to generalize this by checking the + // `merge_at` plus analyzing the selection, but that warrants some reflection... let new_path = if merge_at == created_node.merge_at && parent_type == created_node.parent_type { Some(Arc::new(OpPath::default())) @@ -4414,7 +4868,7 @@ fn handle_requires( parent_node_id: *created_node_id, path_in_parent: new_path, }; - dependency_graph.add_parent(new_node_id, new_parent_relation); + dependency_graph.add_parent(post_requires_node_id, new_parent_relation); } add_post_require_inputs( @@ -4425,17 +4879,16 @@ fn handle_requires( query_graph_edge_id, context, fetch_node_id, - new_node_id, + post_requires_node_id, )?; - created_nodes.extend(new_created_nodes); - created_nodes.insert(new_node_id); + created_nodes.insert(post_requires_node_id); let initial_fetch_path = create_fetch_initial_path( &dependency_graph.supergraph_schema, &entity_type_position.clone().into(), context, )?; let new_path = fetch_node_path.for_new_key_fetch(initial_fetch_path); - Ok((new_node_id, new_path)) + Ok((post_requires_node_id, new_path)) } } @@ -4815,6 +5268,9 @@ mod tests { FetchDataPathElement::TypenameEquals(_) => { unimplemented!() } + FetchDataPathElement::Parent => { + unimplemented!() + } }) .join(".") ) diff --git a/apollo-federation/src/query_plan/mod.rs b/apollo-federation/src/query_plan/mod.rs index d8c90c2c4a..313b9f6322 100644 --- a/apollo-federation/src/query_plan/mod.rs +++ b/apollo-federation/src/query_plan/mod.rs @@ -88,7 +88,8 @@ pub struct FetchNode { /// received from a fetch (and before it is applied to the current in-memory results). pub output_rewrites: Vec>, /// Similar to the other kinds of rewrites. This is a mechanism to convert a contextual path into - /// an argument to a resolver + /// an argument to a resolver. Note value setters are currently unused here, but may be used in + /// the future. pub context_rewrites: Vec>, } @@ -193,7 +194,7 @@ pub struct ConditionNode { /// /// A rewrite usually identifies some sub-part of the data and some action to perform on that /// sub-part. -#[derive(Debug, Clone, PartialEq, Serialize)] +#[derive(Debug, Clone, PartialEq, Serialize, derive_more::From)] pub enum FetchDataRewrite { ValueSetter(FetchDataValueSetter), KeyRenamer(FetchDataKeyRenamer), @@ -219,9 +220,10 @@ pub struct FetchDataKeyRenamer { } /// Vectors of this element match path(s) to a value in fetch data. Each element is (1) a key in -/// object data, (2) _any_ index in array data (often serialized as `@`), or (3) a typename -/// constraint on the object data at that point in the path(s) (a path should only match for objects -/// whose `__typename` is the provided type). +/// object data, (2) _any_ index in array data (often serialized as `@`), (3) a typename constraint +/// on the object data at that point in the path(s) (a path should only match for objects whose +/// `__typename` is the provided type), or (4) a parent indicator to move upwards one level in the +/// object. /// /// It's possible for vectors of this element to match no paths in fetch data, e.g. if an object key /// doesn't exist, or if an object's `__typename` doesn't equal the provided one. If this occurs, @@ -238,6 +240,7 @@ pub enum FetchDataPathElement { Key(Name, Conditions), AnyIndex(Conditions), TypenameEquals(Name), + Parent, } pub type Conditions = Vec; diff --git a/apollo-federation/src/query_plan/query_planner.rs b/apollo-federation/src/query_plan/query_planner.rs index f6f4062760..ed2a4b2589 100644 --- a/apollo-federation/src/query_plan/query_planner.rs +++ b/apollo-federation/src/query_plan/query_planner.rs @@ -3,7 +3,6 @@ use std::num::NonZeroU32; use std::ops::Deref; use std::sync::Arc; -use apollo_compiler::collections::HashSet; use apollo_compiler::collections::IndexMap; use apollo_compiler::collections::IndexSet; use apollo_compiler::validation::Valid; @@ -52,9 +51,7 @@ use crate::utils::logging::snapshot; use crate::ApiSchemaOptions; use crate::Supergraph; -pub(crate) const CONTEXT_DIRECTIVE: &str = "context"; - -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Clone, Hash, Serialize)] pub struct QueryPlannerConfig { /// Whether the query planner should try to reuse the named fragments of the planned query in /// subgraph fetches. @@ -117,7 +114,7 @@ impl Default for QueryPlannerConfig { } } -#[derive(Debug, Clone, Default, Hash)] +#[derive(Debug, Clone, Default, Hash, Serialize)] pub struct QueryPlanIncrementalDeliveryConfig { /// Enables `@defer` support in the query planner, breaking up the query plan with [DeferNode]s /// as appropriate. @@ -128,10 +125,11 @@ pub struct QueryPlanIncrementalDeliveryConfig { /// Defaults to false. /// /// [DeferNode]: crate::query_plan::DeferNode + #[serde(default)] pub enable_defer: bool, } -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Clone, Hash, Serialize)] pub struct QueryPlannerDebugConfig { /// If used and the supergraph is built from a single subgraph, then user queries do not go /// through the normal query planning and instead a fetch to the one subgraph is built directly @@ -209,10 +207,10 @@ pub struct QueryPlanOptions { } #[derive(Debug, Default, Clone)] -pub(crate) struct EnabledOverrideConditions(HashSet); +pub(crate) struct EnabledOverrideConditions(IndexSet); impl Deref for EnabledOverrideConditions { - type Target = HashSet; + type Target = IndexSet; fn deref(&self) -> &Self::Target { &self.0 @@ -244,7 +242,6 @@ impl QueryPlanner { config: QueryPlannerConfig, ) -> Result { config.assert_valid(); - Self::check_unsupported_features(supergraph)?; let supergraph_schema = supergraph.schema.clone(); let api_schema = supergraph.to_api_schema(ApiSchemaOptions { @@ -488,7 +485,7 @@ impl QueryPlanner { .clone() .into(), config: self.config.clone(), - override_conditions: EnabledOverrideConditions(HashSet::from_iter( + override_conditions: EnabledOverrideConditions(IndexSet::from_iter( options.override_conditions, )), fetch_id_generator: Arc::new(FetchIdGenerator::new()), @@ -568,36 +565,6 @@ impl QueryPlanner { pub fn api_schema(&self) -> &ValidFederationSchema { &self.api_schema } - - fn check_unsupported_features(supergraph: &Supergraph) -> Result<(), FederationError> { - // We will only check for `@context` direcive, since - // `@fromContext` can only be used if `@context` is already - // applied, and we assume a correctly composed supergraph. - // - // `@context` can only be applied on Object Types, Interface - // Types and Unions. For simplicity of this function, we just - // check all 'extended_type` directives. - let has_set_context = supergraph - .schema - .schema() - .types - .values() - .any(|extended_type| extended_type.directives().has(CONTEXT_DIRECTIVE)); - if has_set_context { - let message = "\ - `experimental_query_planner_mode: new` or `both` cannot yet \ - be used with `@context`. \ - Remove uses of `@context` to try the experimental query planner, \ - otherwise switch back to `legacy` or `both_best_effort`.\ - "; - return Err(SingleFederationError::UnsupportedFeature { - message: message.to_owned(), - kind: crate::error::UnsupportedFeatureKind::Context, - } - .into()); - } - Ok(()) - } } fn compute_root_serial_dependency_graph( diff --git a/apollo-federation/src/query_plan/query_planning_traversal.rs b/apollo-federation/src/query_plan/query_planning_traversal.rs index 055498218f..21585e1b73 100644 --- a/apollo-federation/src/query_plan/query_planning_traversal.rs +++ b/apollo-federation/src/query_plan/query_planning_traversal.rs @@ -1060,17 +1060,16 @@ impl<'a: 'b, 'b> QueryPlanningTraversal<'a, 'b> { context: &OpGraphPathContext, excluded_destinations: &ExcludedDestinations, excluded_conditions: &ExcludedConditions, + extra_conditions: Option<&SelectionSet>, ) -> Result { let graph = &self.parameters.federated_query_graph; let head = graph.edge_endpoints(edge)?.0; // Note: `QueryPlanningTraversal::resolve` method asserts that the edge has conditions before // calling this method. - let edge_conditions = graph - .edge_weight(edge)? - .conditions - .as_ref() - .unwrap() - .as_ref(); + let edge_conditions = match extra_conditions { + Some(set) => set, + None => graph.edge_weight(edge)?.conditions.as_ref().unwrap(), + }; let parameters = QueryPlanningParameters { head, head_must_be_root: graph.node_weight(head)?.is_root_node(), @@ -1104,6 +1103,7 @@ impl<'a: 'b, 'b> QueryPlanningTraversal<'a, 'b> { Some(best_plan) => Ok(ConditionResolution::Satisfied { cost: best_plan.cost, path_tree: Some(best_plan.path_tree), + context_map: None, }), None => Ok(ConditionResolution::unsatisfied_conditions()), } @@ -1169,31 +1169,42 @@ impl<'a: 'b, 'b> PlanBuilder> for QueryPlanningTravers // implement `ConditionResolver` trait along with `resolver_cache` field. impl<'a> ConditionResolver for QueryPlanningTraversal<'a, '_> { /// A query plan resolver for edge conditions that caches the outcome per edge. + #[track_caller] fn resolve( &mut self, edge: EdgeIndex, context: &OpGraphPathContext, excluded_destinations: &ExcludedDestinations, excluded_conditions: &ExcludedConditions, + extra_conditions: Option<&SelectionSet>, ) -> Result { // Invariant check: The edge must have conditions. let graph = &self.parameters.federated_query_graph; let edge_data = graph.edge_weight(edge)?; assert!( - edge_data.conditions.is_some(), + edge_data.conditions.is_some() || extra_conditions.is_some(), "Should not have been called for edge without conditions" ); - let cache_result = - self.resolver_cache - .contains(edge, context, excluded_destinations, excluded_conditions); + let cache_result = self.resolver_cache.contains( + edge, + context, + excluded_destinations, + excluded_conditions, + extra_conditions, + ); if let ConditionResolutionCacheResult::Hit(cached_resolution) = cache_result { return Ok(cached_resolution); } - let resolution = - self.resolve_condition_plan(edge, context, excluded_destinations, excluded_conditions)?; + let resolution = self.resolve_condition_plan( + edge, + context, + excluded_destinations, + excluded_conditions, + extra_conditions, + )?; // See if this resolution is eligible to be inserted into the cache. if cache_result.is_miss() { self.resolver_cache diff --git a/apollo-federation/src/schema/position.rs b/apollo-federation/src/schema/position.rs index 5de2402f8c..377968542e 100644 --- a/apollo-federation/src/schema/position.rs +++ b/apollo-federation/src/schema/position.rs @@ -2038,7 +2038,7 @@ impl Debug for ObjectFieldDefinitionPosition { } } -#[derive(Clone, PartialEq, Eq, Hash)] +#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub(crate) struct ObjectFieldArgumentDefinitionPosition { pub(crate) type_name: Name, pub(crate) field_name: Name, diff --git a/apollo-federation/src/subgraph/spec.rs b/apollo-federation/src/subgraph/spec.rs index 44ba278309..4e8676e498 100644 --- a/apollo-federation/src/subgraph/spec.rs +++ b/apollo-federation/src/subgraph/spec.rs @@ -38,9 +38,11 @@ use crate::subgraph::spec::FederationSpecError::UnsupportedFederationDirective; use crate::subgraph::spec::FederationSpecError::UnsupportedVersionError; pub const COMPOSE_DIRECTIVE_NAME: Name = name!("composeDirective"); +pub const CONTEXT_DIRECTIVE_NAME: Name = name!("context"); pub const KEY_DIRECTIVE_NAME: Name = name!("key"); pub const EXTENDS_DIRECTIVE_NAME: Name = name!("extends"); pub const EXTERNAL_DIRECTIVE_NAME: Name = name!("external"); +pub const FROM_CONTEXT_DIRECTIVE_NAME: Name = name!("fromContext"); pub const INACCESSIBLE_DIRECTIVE_NAME: Name = name!("inaccessible"); pub const INTF_OBJECT_DIRECTIVE_NAME: Name = name!("interfaceObject"); pub const OVERRIDE_DIRECTIVE_NAME: Name = name!("override"); @@ -48,8 +50,6 @@ pub const PROVIDES_DIRECTIVE_NAME: Name = name!("provides"); pub const REQUIRES_DIRECTIVE_NAME: Name = name!("requires"); pub const SHAREABLE_DIRECTIVE_NAME: Name = name!("shareable"); pub const TAG_DIRECTIVE_NAME: Name = name!("tag"); -pub const CONTEXT_DIRECTIVE_NAME: Name = name!("context"); -pub const FROM_CONTEXT_DIRECTIVE_NAME: Name = name!("fromContext"); pub const FIELDSET_SCALAR_NAME: Name = name!("FieldSet"); // federated types @@ -68,11 +68,13 @@ pub const FEDERATION_V1_DIRECTIVE_NAMES: [Name; 5] = [ REQUIRES_DIRECTIVE_NAME, ]; -pub const FEDERATION_V2_DIRECTIVE_NAMES: [Name; 11] = [ +pub const FEDERATION_V2_DIRECTIVE_NAMES: [Name; 13] = [ COMPOSE_DIRECTIVE_NAME, + CONTEXT_DIRECTIVE_NAME, KEY_DIRECTIVE_NAME, EXTENDS_DIRECTIVE_NAME, EXTERNAL_DIRECTIVE_NAME, + FROM_CONTEXT_DIRECTIVE_NAME, INACCESSIBLE_DIRECTIVE_NAME, INTF_OBJECT_DIRECTIVE_NAME, OVERRIDE_DIRECTIVE_NAME, @@ -86,9 +88,11 @@ pub const FEDERATION_V2_DIRECTIVE_NAMES: [Name; 11] = [ // in FederationSpecDefinitions.directive_definition() for more information. enum FederationDirectiveName { Compose, + Context, Key, Extends, External, + FromContext, Inaccessible, IntfObject, Override, @@ -102,9 +106,14 @@ lazy_static! { static ref FEDERATION_DIRECTIVE_NAMES_TO_ENUM: IndexMap = { IndexMap::from_iter([ (COMPOSE_DIRECTIVE_NAME, FederationDirectiveName::Compose), + (CONTEXT_DIRECTIVE_NAME, FederationDirectiveName::Context), (KEY_DIRECTIVE_NAME, FederationDirectiveName::Key), (EXTENDS_DIRECTIVE_NAME, FederationDirectiveName::Extends), (EXTERNAL_DIRECTIVE_NAME, FederationDirectiveName::External), + ( + FROM_CONTEXT_DIRECTIVE_NAME, + FederationDirectiveName::FromContext, + ), ( INACCESSIBLE_DIRECTIVE_NAME, FederationDirectiveName::Inaccessible, @@ -285,9 +294,11 @@ impl FederationSpecDefinitions { }; Ok(match enum_name { FederationDirectiveName::Compose => self.compose_directive_definition(alias), + FederationDirectiveName::Context => self.context_directive_definition(alias), FederationDirectiveName::Key => self.key_directive_definition(alias)?, FederationDirectiveName::Extends => self.extends_directive_definition(alias), FederationDirectiveName::External => self.external_directive_definition(alias), + FederationDirectiveName::FromContext => self.from_context_directive_definition(alias), FederationDirectiveName::Inaccessible => self.inaccessible_directive_definition(alias), FederationDirectiveName::IntfObject => { self.interface_object_directive_definition(alias) @@ -339,6 +350,28 @@ impl FederationSpecDefinitions { } } + /// directive @context(name: String!) repeatable on INTERFACE | OBJECT | UNION + fn context_directive_definition(&self, alias: &Option) -> DirectiveDefinition { + DirectiveDefinition { + description: None, + name: alias.clone().unwrap_or(CONTEXT_DIRECTIVE_NAME), + arguments: vec![InputValueDefinition { + description: None, + name: name!("name"), + ty: ty!(String!).into(), + default_value: None, + directives: Default::default(), + } + .into()], + repeatable: true, + locations: vec![ + DirectiveLocation::Interface, + DirectiveLocation::Object, + DirectiveLocation::Union, + ], + } + } + /// directive @key(fields: FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE fn key_directive_definition( &self, @@ -388,6 +421,29 @@ impl FederationSpecDefinitions { } } + // The directive is named `@fromContex`. This is confusing for clippy, as + // `from` is a conventional prefix used in conversion methods, which do not + // take `self` as an argument. This function does **not** perform + // conversion, but extracts `@fromContext` directive definition. + /// directive @fromContext(field: String!) on ARGUMENT_DEFINITION + #[allow(clippy::wrong_self_convention)] + fn from_context_directive_definition(&self, alias: &Option) -> DirectiveDefinition { + DirectiveDefinition { + description: None, + name: alias.clone().unwrap_or(FROM_CONTEXT_DIRECTIVE_NAME), + arguments: vec![InputValueDefinition { + description: None, + name: name!("field"), + ty: ty!(String!).into(), + default_value: None, + directives: Default::default(), + } + .into()], + repeatable: false, + locations: vec![DirectiveLocation::ArgumentDefinition], + } + } + /// directive @inaccessible on /// | ARGUMENT_DEFINITION /// | ENUM diff --git a/apollo-federation/src/supergraph/mod.rs b/apollo-federation/src/supergraph/mod.rs index 6ce40a6f48..2ae9173201 100644 --- a/apollo-federation/src/supergraph/mod.rs +++ b/apollo-federation/src/supergraph/mod.rs @@ -47,10 +47,12 @@ pub use self::subgraph::ValidFederationSubgraphs; use crate::error::FederationError; use crate::error::MultipleFederationErrors; use crate::error::SingleFederationError; +use crate::link::context_spec_definition::CONTEXT_VERSIONS; use crate::link::cost_spec_definition::CostSpecDefinition; use crate::link::federation_spec_definition::get_federation_spec_definition_from_subgraph; use crate::link::federation_spec_definition::FederationSpecDefinition; use crate::link::federation_spec_definition::FEDERATION_VERSIONS; +use crate::link::join_spec_definition::ContextArgument; use crate::link::join_spec_definition::FieldDirectiveArguments; use crate::link::join_spec_definition::JoinSpecDefinition; use crate::link::join_spec_definition::TypeDirectiveArguments; @@ -300,6 +302,7 @@ fn extract_subgraphs_from_fed_2_supergraph( supergraph_schema, subgraphs, graph_enum_value_name_to_subgraph_name, + federation_spec_definitions, join_spec_definition, &union_types, )?; @@ -710,6 +713,16 @@ fn extract_object_type_content( message: "@join__implements should exist for a fed2 supergraph".to_owned(), })?; + let context = supergraph_schema + .metadata() + .and_then(|metadata| metadata.for_identity(&Identity::context_identity())) + .and_then(|context_link| CONTEXT_VERSIONS.find(&context_link.url.version)) + .and_then(|context_spec_def| { + context_spec_def + .context_directive_name_in_schema(supergraph_schema) + .ok() + .map(|name_in_schema| (context_spec_def, name_in_schema)) + }); for TypeInfo { name: type_name, subgraph_info, @@ -748,6 +761,17 @@ fn extract_object_type_content( )?; } + if let Some((_context_spec_def, name_in_supergraph)) = &context { + apply_context_to_type( + type_, + subgraphs, + graph_enum_value_name_to_subgraph_name, + federation_spec_definitions, + name_in_supergraph, + &CompositeTypeDefinitionPosition::Object(pos.clone()), + )?; + } + for graph_enum_value in subgraph_info.keys() { let subgraph = get_subgraph( subgraphs, @@ -891,10 +915,10 @@ fn extract_interface_type_content( subgraph_info, } in info.iter() { - let type_ = InterfaceTypeDefinitionPosition { + let pos = InterfaceTypeDefinitionPosition { type_name: (*type_name).clone(), - } - .get(supergraph_schema.schema())?; + }; + let type_ = pos.get(supergraph_schema.schema())?; fn get_pos( subgraph: &FederationSubgraph, subgraph_info: &IndexMap, @@ -974,6 +998,27 @@ fn extract_interface_type_content( } } + let context = supergraph_schema + .metadata() + .and_then(|metadata| metadata.for_identity(&Identity::context_identity())) + .and_then(|context_link| CONTEXT_VERSIONS.find(&context_link.url.version)) + .and_then(|context_spec_def| { + context_spec_def + .context_directive_name_in_schema(supergraph_schema) + .ok() + .map(|name_in_schema| (context_spec_def, name_in_schema)) + }); + if let Some((_context_spec_def, name_in_supergraph)) = &context { + apply_context_to_type( + type_, + subgraphs, + graph_enum_value_name_to_subgraph_name, + federation_spec_definitions, + name_in_supergraph, + &CompositeTypeDefinitionPosition::Interface(pos.clone()), + )?; + } + for (field_name, field) in type_.fields.iter() { let mut field_directive_applications = Vec::new(); for directive in field.directives.get_all(&field_directive_definition.name) { @@ -1067,6 +1112,7 @@ fn extract_union_type_content( supergraph_schema: &FederationSchema, subgraphs: &mut FederationSubgraphs, graph_enum_value_name_to_subgraph_name: &IndexMap>, + federation_spec_definitions: &IndexMap, join_spec_definition: &JoinSpecDefinition, info: &[TypeInfo], ) -> Result<(), FederationError> { @@ -1150,6 +1196,28 @@ fn extract_union_type_content( )?; } } + + let context = supergraph_schema + .metadata() + .and_then(|metadata| metadata.for_identity(&Identity::context_identity())) + .and_then(|context_link| CONTEXT_VERSIONS.find(&context_link.url.version)) + .and_then(|context_spec_def| { + context_spec_def + .context_directive_name_in_schema(supergraph_schema) + .ok() + .map(|name_in_schema| (context_spec_def, name_in_schema)) + }); + + if let Some((_context_spec_def, name_in_supergraph)) = &context { + apply_context_to_type( + type_, + subgraphs, + graph_enum_value_name_to_subgraph_name, + federation_spec_definitions, + name_in_supergraph, + &CompositeTypeDefinitionPosition::Union(pos.clone()), + )?; + } } Ok(()) @@ -1390,6 +1458,7 @@ fn add_subgraph_field( override_: None, override_label: None, user_overridden: None, + context_arguments: None, }); let subgraph_field_type = match &field_directive_application.type_ { Some(t) => decode_type(t)?, @@ -1475,6 +1544,40 @@ fn add_subgraph_field( )?; } + if let Some(context_arguments) = &field_directive_application.context_arguments { + for args in context_arguments { + let ContextArgument { + name, + type_, + context, + selection, + } = args; + let (_, context_name_in_subgraph) = context.rsplit_once("__").ok_or_else(|| { + SingleFederationError::InvalidFederationSupergraph { + message: format!( + "Could not parse context field from supergraph '{}'", + context + ) + .to_owned(), + } + })?; + + let arg = format!("${} {}", context_name_in_subgraph, selection); + let from_context_directive = + federation_spec_definition.from_context_directive(&subgraph.schema, arg)?; + let directives = std::iter::once(from_context_directive).collect(); + let ty = decode_type(type_)?; + let node = Node::new(InputValueDefinition { + name: Name::new(name)?, + ty: ty.into(), + directives, + default_value: None, + description: None, + }); + subgraph_field.arguments.push(node); + } + } + match object_or_interface_field_definition_position { ObjectOrInterfaceFieldDefinitionPosition::Object(pos) => { pos.insert(&mut subgraph.schema, Component::from(subgraph_field))?; @@ -1505,6 +1608,7 @@ fn add_subgraph_input_field( override_: None, override_label: None, user_overridden: None, + context_arguments: None, }); let subgraph_input_field_type = match &field_directive_application.type_ { Some(t) => Node::new(decode_type(t)?), @@ -1562,6 +1666,16 @@ fn get_subgraph<'subgraph>( }) } +fn get_index_from_subgraph_name<'a>( + graph_enum_value_name_to_subgraph_name: &'a IndexMap>, + subgraph_name: &'a Name, +) -> Option<&'a Name> { + graph_enum_value_name_to_subgraph_name + .iter() + .find(|(_, v)| v.as_ref() == subgraph_name.as_str()) + .map(|(k, _)| k) +} + lazy_static! { static ref EXECUTABLE_DIRECTIVE_LOCATIONS: IndexSet = { [ @@ -1579,6 +1693,103 @@ lazy_static! { }; } +fn insert_directive( + schema: &mut FederationSchema, + pos: &CompositeTypeDefinitionPosition, + directive: Component, +) -> Result<(), FederationError> { + match pos { + CompositeTypeDefinitionPosition::Union(pos) => pos.insert_directive(schema, directive), + CompositeTypeDefinitionPosition::Object(pos) => pos.insert_directive(schema, directive), + CompositeTypeDefinitionPosition::Interface(pos) => pos.insert_directive(schema, directive), + } +} + +trait CompositeType { + fn directives(&self) -> &DirectiveList; +} + +impl CompositeType for UnionType { + fn directives(&self) -> &DirectiveList { + &self.directives + } +} + +impl CompositeType for ObjectType { + fn directives(&self) -> &DirectiveList { + &self.directives + } +} + +impl CompositeType for InterfaceType { + fn directives(&self) -> &DirectiveList { + &self.directives + } +} + +fn apply_context_to_type( + ty: &Node, + subgraphs: &mut FederationSubgraphs, + graph_enum_value_name_to_subgraph_name: &IndexMap>, + federation_spec_definitions: &IndexMap, + context_name_in_supergraph: &Name, + pos: &CompositeTypeDefinitionPosition, +) -> Result<(), FederationError> +where + T: CompositeType, +{ + for directive in ty.directives().get_all(context_name_in_supergraph.as_str()) { + FederationSpecDefinition::context_directive_arguments(directive).and_then( + |context_name| { + let mut arr = context_name.name.split("__"); + let subgraph_name = arr.next().ok_or_else(|| { + SingleFederationError::InvalidFederationSupergraph { + message: format!( + "Could not parse context name from supergraph '{}'", + context_name_in_supergraph + ) + .to_owned(), + } + })?; + let subgraph_name = Name::new_unchecked(subgraph_name); + let subgraph_index = get_index_from_subgraph_name( + graph_enum_value_name_to_subgraph_name, + &subgraph_name, + ) + .ok_or_else(|| SingleFederationError::InvalidSubgraph { + message: format!("Could not look up subgraph by name '{}'", subgraph_name) + .to_owned(), + })?; + let subgraph = get_subgraph( + subgraphs, + graph_enum_value_name_to_subgraph_name, + subgraph_index, + )?; + + let federation_spec_definition = federation_spec_definitions + .get(subgraph_index) + .ok_or_else(|| SingleFederationError::InvalidFederationSupergraph { + message: "Subgraph unexpectedly does not use federation spec".to_owned(), + })?; + let context_in_subgraph = arr.last().ok_or_else(|| { + SingleFederationError::InvalidFederationSupergraph { + message: format!( + "Could not parse context name from supergraph '{}'", + context_name_in_supergraph + ) + .to_owned(), + } + })?; + let context_directive = federation_spec_definition + .context_directive(&subgraph.schema, context_in_subgraph.to_string())?; + insert_directive(&mut subgraph.schema, pos, context_directive.into())?; + Ok(()) + }, + )?; + } + Ok(()) +} + fn remove_unused_types_from_subgraph(schema: &mut FederationSchema) -> Result<(), FederationError> { // We now do an additional path on all types because we sometimes added types to subgraphs // without being sure that the subgraph had the type in the first place (especially with the diff --git a/apollo-federation/src/supergraph/schema.rs b/apollo-federation/src/supergraph/schema.rs index 589131f633..82154f0d2e 100644 --- a/apollo-federation/src/supergraph/schema.rs +++ b/apollo-federation/src/supergraph/schema.rs @@ -99,6 +99,10 @@ pub(crate) fn new_empty_fed_2_subgraph_schema() -> Result(&mut self, mut init: O, mut mapper: F) -> Result + where + Self: Iterator, + F: FnMut(O, T) -> Result, + { + for item in self { + init = mapper(init, item)?; + } + Ok(init) + } + + fn and_then_fold(&mut self, mut init: O, mut mapper: F) -> Result + where + Self: Iterator>, + F: FnMut(O, T) -> Result, + { + for item in self { + init = mapper(init, item?)? + } + Ok(init) + } } impl FallibleIterator for I {} diff --git a/apollo-federation/tests/extract_subgraphs.rs b/apollo-federation/tests/extract_subgraphs.rs index 2148185184..9fbde4e473 100644 --- a/apollo-federation/tests/extract_subgraphs.rs +++ b/apollo-federation/tests/extract_subgraphs.rs @@ -697,3 +697,111 @@ fn does_not_extract_renamed_demand_control_directive_name_conflicts() { } insta::assert_snapshot!(snapshot); } + +#[test] +fn extracts_set_context_directives() { + let subgraphs = Supergraph::new(r#" + schema + @link(url: "https://specs.apollo.dev/link/v1.0") + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) + @link(url: "https://specs.apollo.dev/context/v0.1") + { + query: Query + } + + directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA + + directive @join__graph(name: String!, url: String!) on ENUM_VALUE + + directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true, isInterfaceObject: Boolean! = false) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + + directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + + directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE + + directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on UNION + + directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE + + directive @join__directive(graphs: [join__Graph!], name: String!, args: join__DirectiveArguments) repeatable on SCHEMA | OBJECT | INTERFACE | FIELD_DEFINITION + + directive @context(name: String!) repeatable on INTERFACE | OBJECT | UNION + + directive @context__fromContext(field: String) on ARGUMENT_DEFINITION + + enum link__Purpose { + """ + \`SECURITY\` features provide metadata necessary to securely resolve fields. + """ + SECURITY + + """ + \`EXECUTION\` features provide metadata necessary for operation execution. + """ + EXECUTION + } + + scalar link__Import + + enum join__Graph { + SUBGRAPH1 @join__graph(name: "Subgraph1", url: "") + SUBGRAPH2 @join__graph(name: "Subgraph2", url: "") + } + + scalar join__FieldSet + + scalar join__DirectiveArguments + + scalar join__FieldValue + + input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! + } + + scalar context__context + + type Query + @join__type(graph: SUBGRAPH1) + @join__type(graph: SUBGRAPH2) + { + t: T! @join__field(graph: SUBGRAPH1) + a: Int! @join__field(graph: SUBGRAPH2) + } + + type T + @join__type(graph: SUBGRAPH1, key: "id") + @context(name: "Subgraph1__context") + { + id: ID! + u: U! + prop: String! + } + + type U + @join__type(graph: SUBGRAPH1, key: "id") + @join__type(graph: SUBGRAPH2, key: "id") + { + id: ID! + field: Int! @join__field(graph: SUBGRAPH1, contextArguments: [{context: "Subgraph1__context", name: "a", type: "String", selection: "{ prop }"}]) + } + "#) + .expect("is supergraph") + .extract_subgraphs() + .expect("extracts subgraphs"); + + let mut snapshot = String::new(); + for (_name, subgraph) in subgraphs { + use std::fmt::Write; + + _ = writeln!( + &mut snapshot, + "{}\n---\n{}", + subgraph.name, + subgraph.schema.schema() + ); + } + insta::assert_snapshot!(snapshot); +} diff --git a/apollo-federation/tests/query_plan/build_query_plan_tests.rs b/apollo-federation/tests/query_plan/build_query_plan_tests.rs index 13ca9e52bd..c0d85c7b62 100644 --- a/apollo-federation/tests/query_plan/build_query_plan_tests.rs +++ b/apollo-federation/tests/query_plan/build_query_plan_tests.rs @@ -31,6 +31,7 @@ fn some_name() { } */ +mod context; mod debug_max_evaluated_plans_configuration; mod defer; mod fetch_operation_names; diff --git a/apollo-federation/tests/query_plan/build_query_plan_tests/context.rs b/apollo-federation/tests/query_plan/build_query_plan_tests/context.rs new file mode 100644 index 0000000000..4bdf9f41b1 --- /dev/null +++ b/apollo-federation/tests/query_plan/build_query_plan_tests/context.rs @@ -0,0 +1,1491 @@ +// PORT_NOTE: The context tests in the JS code had more involved setup compared to the other tests. +// Here is a snippet from the JS context test leading up to the creation of the planner: +// ```js +// const asFed2Service = (service: ServiceDefinition) => { +// return { +// ...service, +// typeDefs: asFed2SubgraphDocument(service.typeDefs, { +// includeAllImports: true, +// }), +// }; +// }; +// +// const composeAsFed2Subgraphs = (services: ServiceDefinition[]) => { +// return composeServices(services.map((s) => asFed2Service(s))); +// }; +// +// const result = composeAsFed2Subgraphs([subgraph1, subgraph2]); +// const [api, queryPlanner] = [ +// result.schema!.toAPISchema(), +// new QueryPlanner(Supergraph.buildForTests(result.supergraphSdl!)), +// ]; +// ``` +// For all other tests, the set up was a single line: +// ```js +// const [api, queryPlanner] = composeAndCreatePlanner(subgraph1, subgraph2); +// ``` +// +// How this needs to be ported remains to be seen... + +use std::sync::Arc; + +use apollo_compiler::Name; +use apollo_federation::query_plan::FetchDataKeyRenamer; +use apollo_federation::query_plan::FetchDataPathElement; +use apollo_federation::query_plan::FetchDataRewrite; +use apollo_federation::query_plan::PlanNode; +use apollo_federation::query_plan::TopLevelPlanNode; + +#[test] +fn set_context_test_variable_is_from_same_subgraph() { + let planner = planner!( + Subgraph1: r#" + type Query { + t: T! + } + type T @key(fields: "id") @context(name: "context") { + id: ID! + u: U! + prop: String! + } + type U @key(fields: "id") { + id: ID! + b: String! + field(a: String @fromContext(field: "$context { prop }")): Int! + } + "#, + Subgraph2: r#" + type Query { + a: Int! + } + type U @key(fields: "id") { + id: ID! + } + "#, + ); + + let plan = assert_plan!(planner, + r#" + { + t { + u { + b + field + } + } + } + "#, + @r###" + QueryPlan { + Sequence { + Fetch(service: "Subgraph1") { + { + t { + __typename + prop + u { + __typename + id + b + } + } + } + }, + Flatten(path: "t.u") { + Fetch(service: "Subgraph1") { + { + ... on U { + __typename + id + } + } => + { + ... on U { + field(a: $contextualArgument_1_0) + } + } + }, + }, + }, + } + "### + ); + match plan.node { + Some(TopLevelPlanNode::Sequence(node)) => match node.nodes.get(1) { + Some(PlanNode::Flatten(node)) => match &*node.node { + PlanNode::Fetch(node) => { + assert_eq!( + node.context_rewrites, + vec![Arc::new(FetchDataRewrite::KeyRenamer( + FetchDataKeyRenamer { + rename_key_to: Name::new("contextualArgument_1_0").unwrap(), + path: vec![ + FetchDataPathElement::Parent, + FetchDataPathElement::TypenameEquals(Name::new("T").unwrap()), + FetchDataPathElement::Key( + Name::new("prop").unwrap(), + Default::default() + ), + ], + } + )),] + ); + } + _ => panic!("failed to get fetch node"), + }, + _ => panic!("failed to get flatten node"), + }, + _ => panic!("failed to get sequence node"), + } +} + +#[test] +fn set_context_test_variable_is_from_different_subgraph() { + let planner = planner!( + Subgraph1: r#" + type Query { + t: T! + } + type T @key(fields: "id") @context(name: "context") { + id: ID! + u: U! + prop: String! @external + } + type U @key(fields: "id") { + id: ID! + field(a: String @fromContext(field: "$context { prop }")): Int! + } + "#, + Subgraph2: r#" + type Query { + a: Int! + } + type T @key(fields: "id") { + id: ID! + prop: String! + } + type U @key(fields: "id") { + id: ID! + } + "#, + ); + let plan = assert_plan!( + planner, + r#" + { + t { + u { + id + field + } + } + } + "#, + @r###" + QueryPlan { + Sequence { + Fetch(service: "Subgraph1") { + { + t { + __typename + id + u { + __typename + id + } + } + } + }, + Flatten(path: "t") { + Fetch(service: "Subgraph2") { + { + ... on T { + __typename + id + } + } => + { + ... on T { + prop + } + } + }, + }, + Flatten(path: "t.u") { + Fetch(service: "Subgraph1") { + { + ... on U { + __typename + id + } + } => + { + ... on U { + field(a: $contextualArgument_1_0) + } + } + }, + }, + }, + } + "###); + + match plan.node { + Some(TopLevelPlanNode::Sequence(node)) => match node.nodes.get(2) { + Some(PlanNode::Flatten(node)) => match &*node.node { + PlanNode::Fetch(node) => { + assert_eq!( + node.context_rewrites, + vec![Arc::new(FetchDataRewrite::KeyRenamer( + FetchDataKeyRenamer { + rename_key_to: Name::new("contextualArgument_1_0").unwrap(), + path: vec![ + FetchDataPathElement::Parent, + FetchDataPathElement::TypenameEquals(Name::new("T").unwrap()), + FetchDataPathElement::Key( + Name::new("prop").unwrap(), + Default::default() + ), + ], + } + )),] + ); + } + _ => panic!("failed to get fetch node"), + }, + _ => panic!("failed to get flatten node"), + }, + _ => panic!("failed to get sequence node"), + } +} + +#[test] +fn set_context_test_variable_is_already_in_a_different_fetch_group() { + let planner = planner!( + Subgraph1: r#" + type Query { + t: T! + } + type T @key(fields: "id") { + id: ID! + u: U! + prop: String! + } + type U @key(fields: "id") { + id: ID! + } + "#, + Subgraph2: r#" + type Query { + a: Int! + } + + type T @key(fields: "id") @context(name: "context") { + id: ID! + prop: String! @external + } + + type U @key(fields: "id") { + id: ID! + field(a: String @fromContext(field: "$context { prop }")): Int! + } + "#, + ); + + let plan = assert_plan!(planner, + r#" + { + t { + u { + id + field + } + } + } + "#, + @r###" + QueryPlan { + Sequence { + Fetch(service: "Subgraph1") { + { + t { + __typename + prop + u { + __typename + id + } + } + } + }, + Flatten(path: "t.u") { + Fetch(service: "Subgraph2") { + { + ... on U { + __typename + id + } + } => + { + ... on U { + field(a: $contextualArgument_1_0) + } + } + }, + }, + }, + } + "### + ); + match plan.node { + Some(TopLevelPlanNode::Sequence(node)) => match node.nodes.get(1) { + Some(PlanNode::Flatten(node)) => match &*node.node { + PlanNode::Fetch(node) => { + assert_eq!( + node.context_rewrites, + vec![Arc::new(FetchDataRewrite::KeyRenamer( + FetchDataKeyRenamer { + rename_key_to: Name::new("contextualArgument_1_0").unwrap(), + path: vec![ + FetchDataPathElement::Parent, + FetchDataPathElement::TypenameEquals(Name::new("T").unwrap()), + FetchDataPathElement::Key( + Name::new("prop").unwrap(), + Default::default() + ), + ], + } + )),] + ); + } + _ => panic!("failed to get fetch node"), + }, + _ => panic!("failed to get flatten node"), + }, + _ => panic!("failed to get sequence node"), + } +} + +#[test] +fn set_context_test_variable_is_a_list() { + let planner = planner!( + Subgraph1: r#" + type Query { + t: T! + } + type T @key(fields: "id") @context(name: "context") { + id: ID! + u: U! + prop: [String]! + } + type U @key(fields: "id") { + id: ID! + field(a: [String] @fromContext(field: "$context { prop }")): Int! + } + "#, + Subgraph2: r#" + type Query { + a: Int! + } + type U @key(fields: "id") { + id: ID! + } + "# + ); + + let plan = assert_plan!(planner, + r#" + { + t { + u { + field + } + } + } + "#, + @r###" + QueryPlan { + Sequence { + Fetch(service: "Subgraph1") { + { + t { + __typename + prop + u { + __typename + id + } + } + } + }, + Flatten(path: "t.u") { + Fetch(service: "Subgraph1") { + { + ... on U { + __typename + id + } + } => + { + ... on U { + field(a: $contextualArgument_1_0) + } + } + }, + }, + }, + } + "### + ); + match plan.node { + Some(TopLevelPlanNode::Sequence(node)) => match node.nodes.get(1) { + Some(PlanNode::Flatten(node)) => match &*node.node { + PlanNode::Fetch(node) => { + assert_eq!( + node.context_rewrites, + vec![Arc::new(FetchDataRewrite::KeyRenamer( + FetchDataKeyRenamer { + rename_key_to: Name::new("contextualArgument_1_0").unwrap(), + path: vec![ + FetchDataPathElement::Parent, + FetchDataPathElement::TypenameEquals(Name::new("T").unwrap()), + FetchDataPathElement::Key( + Name::new("prop").unwrap(), + Default::default() + ), + ], + } + )),] + ); + } + _ => panic!("failed to get fetch node"), + }, + _ => panic!("failed to get flatten node"), + }, + _ => panic!("failed to get sequence node"), + } +} + +#[test] +fn set_context_test_fetched_as_a_list() { + let planner = planner!( + Subgraph1: r#" + type Query { + t: [T]! + } + type T @key(fields: "id") @context(name: "context") { + id: ID! + u: U! + prop: String! + } + type U @key(fields: "id") { + id: ID! + b: String! + field(a: String @fromContext(field: "$context { prop }")): Int! + } + "#, + Subgraph2: r#" + type Query { + a: Int! + } + type U @key(fields: "id") { + id: ID! + } + "#, + ); + + let plan = assert_plan!(planner, + r#" + { + t { + u { + b + field + } + } + } + "#, + @r###" + QueryPlan { + Sequence { + Fetch(service: "Subgraph1") { + { + t { + __typename + prop + u { + __typename + id + b + } + } + } + }, + Flatten(path: "t.@.u") { + Fetch(service: "Subgraph1") { + { + ... on U { + __typename + id + } + } => + { + ... on U { + field(a: $contextualArgument_1_0) + } + } + }, + }, + }, + } + "### + ); + match plan.node { + Some(TopLevelPlanNode::Sequence(node)) => match node.nodes.get(1) { + Some(PlanNode::Flatten(node)) => match &*node.node { + PlanNode::Fetch(node) => { + assert_eq!( + node.context_rewrites, + vec![Arc::new(FetchDataRewrite::KeyRenamer( + FetchDataKeyRenamer { + rename_key_to: Name::new("contextualArgument_1_0").unwrap(), + path: vec![ + FetchDataPathElement::Parent, + FetchDataPathElement::TypenameEquals(Name::new("T").unwrap()), + FetchDataPathElement::Key( + Name::new("prop").unwrap(), + Default::default() + ), + ], + } + )),] + ); + } + _ => panic!("failed to get fetch node"), + }, + _ => panic!("failed to get flatten node"), + }, + _ => panic!("failed to get sequence node"), + } +} + +#[test] +fn set_context_test_impacts_on_query_planning() { + let planner = planner!( + Subgraph1: r#" + type Query { + t: I! + } + + interface I @context(name: "context") @key(fields: "id") { + id: ID! + u: U! + prop: String! + } + + type A implements I @key(fields: "id") { + id: ID! + u: U! + prop: String! + } + + type B implements I @key(fields: "id") { + id: ID! + u: U! + prop: String! + } + + type U @key(fields: "id") { + id: ID! + b: String! + field(a: String @fromContext(field: "$context { prop }")): Int! + } + "#, + Subgraph2: r#" + type Query { + a: Int! + } + type U @key(fields: "id") { + id: ID! + } + "#, + ); + + let plan = assert_plan!(planner, + r#" + { + t { + u { + b + field + } + } + } + "#, + @r###" + QueryPlan { + Sequence { + Fetch(service: "Subgraph1") { + { + t { + __typename + prop + u { + __typename + id + b + } + } + } + }, + Flatten(path: "t.u") { + Fetch(service: "Subgraph1") { + { + ... on U { + __typename + id + } + } => + { + ... on U { + field(a: $contextualArgument_1_0) + } + } + }, + }, + }, + } + "### + ); + match plan.node { + Some(TopLevelPlanNode::Sequence(node)) => match node.nodes.get(1) { + Some(PlanNode::Flatten(node)) => match &*node.node { + PlanNode::Fetch(node) => { + assert_eq!( + node.context_rewrites, + vec![ + Arc::new(FetchDataRewrite::KeyRenamer(FetchDataKeyRenamer { + rename_key_to: Name::new("contextualArgument_1_0").unwrap(), + path: vec![ + FetchDataPathElement::Parent, + FetchDataPathElement::TypenameEquals(Name::new("A").unwrap()), + FetchDataPathElement::Key( + Name::new("prop").unwrap(), + Default::default() + ), + ], + })), + Arc::new(FetchDataRewrite::KeyRenamer(FetchDataKeyRenamer { + rename_key_to: Name::new("contextualArgument_1_0").unwrap(), + path: vec![ + FetchDataPathElement::Parent, + FetchDataPathElement::TypenameEquals(Name::new("B").unwrap()), + FetchDataPathElement::Key( + Name::new("prop").unwrap(), + Default::default() + ), + ], + })), + ] + ); + } + _ => panic!("failed to get fetch node"), + }, + _ => panic!("failed to get flatten node"), + }, + _ => panic!("failed to get sequence node"), + } +} + +#[test] +fn set_context_test_with_type_conditions_for_union() { + let planner = planner!( + Subgraph1: r#" + type Query { + t: T! + } + + union T @context(name: "context") = A | B + + type A @key(fields: "id") { + id: ID! + u: U! + prop: String! + } + + type B @key(fields: "id") { + id: ID! + u: U! + prop: String! + } + + type U @key(fields: "id") { + id: ID! + b: String! + field( + a: String + @fromContext( + field: "$context ... on A { prop } ... on B { prop }" + ) + ): Int! + } + "#, + Subgraph2: r#" + type Query { + a: Int! + } + type U @key(fields: "id") { + id: ID! + } + "#, + ); + + let plan = assert_plan!(planner, + r#" + { + t { + ... on A { + u { + b + field + } + } + ... on B { + u { + b + field + } + } + } + } + "#, + @r###" + QueryPlan { + Sequence { + Fetch(service: "Subgraph1") { + { + t { + __typename + ... on A { + __typename + prop + u { + __typename + id + b + } + } + ... on B { + __typename + prop + u { + __typename + id + b + } + } + } + } + }, + Flatten(path: "t.u") { + Fetch(service: "Subgraph1") { + { + ... on U { + __typename + id + } + } => + { + ... on U { + field(a: $contextualArgument_1_0) + } + } + }, + }, + }, + } + "### + ); + match plan.node { + Some(TopLevelPlanNode::Sequence(node)) => match node.nodes.get(1) { + Some(PlanNode::Flatten(node)) => match &*node.node { + PlanNode::Fetch(node) => { + assert_eq!( + node.context_rewrites, + vec![ + Arc::new(FetchDataRewrite::KeyRenamer(FetchDataKeyRenamer { + rename_key_to: Name::new("contextualArgument_1_0").unwrap(), + path: vec![ + FetchDataPathElement::Parent, + FetchDataPathElement::TypenameEquals(Name::new("A").unwrap()), + FetchDataPathElement::Key( + Name::new("prop").unwrap(), + Default::default() + ), + ], + })), + Arc::new(FetchDataRewrite::KeyRenamer(FetchDataKeyRenamer { + rename_key_to: Name::new("contextualArgument_1_0").unwrap(), + path: vec![ + FetchDataPathElement::Parent, + FetchDataPathElement::TypenameEquals(Name::new("B").unwrap()), + FetchDataPathElement::Key( + Name::new("prop").unwrap(), + Default::default() + ), + ], + })), + ] + ); + } + _ => panic!("failed to get fetch node"), + }, + _ => panic!("failed to get flatten node"), + }, + _ => panic!("failed to get sequence node"), + } +} + +#[test] +fn set_context_test_accesses_a_different_top_level_query() { + let planner = planner!( + Subgraph1: r#" + type Query @context(name: "topLevelQuery") { + me: User! + product: Product + } + + type User @key(fields: "id") { + id: ID! + locale: String! + } + + type Product @key(fields: "id") { + id: ID! + price( + locale: String + @fromContext(field: "$topLevelQuery { me { locale } }") + ): Int! + } + "#, + Subgraph2: r#" + type Query { + randomId: ID! + } + + type Product @key(fields: "id") { + id: ID! + } + "#, + ); + + let plan = assert_plan!(planner, + r#" + { + product { + price + } + } + "#, + @r###" + QueryPlan { + Sequence { + Fetch(service: "Subgraph1") { + { + __typename + me { + locale + } + product { + __typename + id + } + } + }, + Flatten(path: "product") { + Fetch(service: "Subgraph1") { + { + ... on Product { + __typename + id + } + } => + { + ... on Product { + price(locale: $contextualArgument_1_0) + } + } + }, + }, + }, + } + "### + ); + match plan.node { + Some(TopLevelPlanNode::Sequence(node)) => match node.nodes.get(1) { + Some(PlanNode::Flatten(node)) => match &*node.node { + PlanNode::Fetch(node) => { + assert_eq!( + node.context_rewrites, + vec![Arc::new(FetchDataRewrite::KeyRenamer( + FetchDataKeyRenamer { + rename_key_to: Name::new("contextualArgument_1_0").unwrap(), + path: vec![ + FetchDataPathElement::Parent, + FetchDataPathElement::Key( + Name::new("me").unwrap(), + Default::default() + ), + FetchDataPathElement::Key( + Name::new("locale").unwrap(), + Default::default() + ), + ], + } + )),] + ); + } + _ => panic!("failed to get fetch node"), + }, + _ => panic!("failed to get flatten node"), + }, + _ => panic!("failed to get sequence node"), + } +} + +#[test] +fn set_context_one_subgraph() { + let planner = planner!( + Subgraph1: r#" + type Query { + t: T! + } + type T @key(fields: "id") @context(name: "context") { + id: ID! + u: U! + prop: String! + } + type U @key(fields: "id") { + id: ID! + b: String! + field(a: String @fromContext(field: "$context { prop }")): Int! + } + "#, + Subgraph2: r#" + type Query { + randomId: ID! + } + "#, + ); + + let plan = assert_plan!(planner, + r#" + { + t { + u { + field + } + } + } + "#, + @r###" + QueryPlan { + Sequence { + Fetch(service: "Subgraph1") { + { + t { + __typename + prop + u { + __typename + id + } + } + } + }, + Flatten(path: "t.u") { + Fetch(service: "Subgraph1") { + { + ... on U { + __typename + id + } + } => + { + ... on U { + field(a: $contextualArgument_1_0) + } + } + }, + }, + }, + } + "### + ); + match plan.node { + Some(TopLevelPlanNode::Sequence(node)) => match node.nodes.get(1) { + Some(PlanNode::Flatten(node)) => match &*node.node { + PlanNode::Fetch(node) => { + assert_eq!( + node.context_rewrites, + vec![Arc::new(FetchDataRewrite::KeyRenamer( + FetchDataKeyRenamer { + rename_key_to: Name::new("contextualArgument_1_0").unwrap(), + path: vec![ + FetchDataPathElement::Parent, + FetchDataPathElement::TypenameEquals(Name::new("T").unwrap()), + FetchDataPathElement::Key( + Name::new("prop").unwrap(), + Default::default() + ), + ], + } + )),] + ); + } + _ => panic!("failed to get fetch node"), + }, + _ => panic!("failed to get flatten node"), + }, + _ => panic!("failed to get sequence node"), + } +} + +#[test] +fn set_context_required_field_is_several_levels_deep_going_back_and_forth_between_subgraphs() { + let planner = planner!( + Subgraph1: r#" + type Query { + t: T! + } + + type A @key(fields: "id") { + id: ID! + b: B! @external + } + + type B @key(fields: "id") { + id: ID! + c: C! + } + + type C @key(fields: "id") { + id: ID! + prop: String! + } + + type T @key(fields: "id") @context(name: "context") { + id: ID! + u: U! + a: A! + } + type U @key(fields: "id") { + id: ID! + b: String! + field( + a: String @fromContext(field: "$context { a { b { c { prop }}} }") + ): Int! + } + "#, + Subgraph2: r#" + type Query { + randomId: ID! + } + + type A @key(fields: "id") { + id: ID! + b: B! + } + + type B @key(fields: "id") { + id: ID! + } + "#, + ); + + let plan = assert_plan!(planner, + r#" + { + t { + u { + field + } + } + } + "#, + @r###" + QueryPlan { + Sequence { + Fetch(service: "Subgraph1") { + { + t { + __typename + a { + __typename + id + } + u { + __typename + id + } + } + } + }, + Flatten(path: "t.a") { + Fetch(service: "Subgraph2") { + { + ... on A { + __typename + id + } + } => + { + ... on A { + b { + __typename + id + } + } + } + }, + }, + Flatten(path: "t.a.b") { + Fetch(service: "Subgraph1") { + { + ... on B { + __typename + id + } + } => + { + ... on B { + c { + prop + } + } + } + }, + }, + Flatten(path: "t.u") { + Fetch(service: "Subgraph1") { + { + ... on U { + __typename + id + } + } => + { + ... on U { + field(a: $contextualArgument_1_0) + } + } + }, + }, + }, + } + "### + ); + match plan.node { + Some(TopLevelPlanNode::Sequence(node)) => match node.nodes.get(3) { + Some(PlanNode::Flatten(node)) => match &*node.node { + PlanNode::Fetch(node) => { + assert_eq!( + node.context_rewrites, + vec![Arc::new(FetchDataRewrite::KeyRenamer( + FetchDataKeyRenamer { + rename_key_to: Name::new("contextualArgument_1_0").unwrap(), + path: vec![ + FetchDataPathElement::Parent, + FetchDataPathElement::TypenameEquals(Name::new("T").unwrap()), + FetchDataPathElement::Key( + Name::new("a").unwrap(), + Default::default() + ), + FetchDataPathElement::Key( + Name::new("b").unwrap(), + Default::default() + ), + FetchDataPathElement::Key( + Name::new("c").unwrap(), + Default::default() + ), + FetchDataPathElement::Key( + Name::new("prop").unwrap(), + Default::default() + ), + ], + } + )),] + ); + } + _ => panic!("failed to get fetch node"), + }, + _ => panic!("failed to get flatten node"), + }, + _ => panic!("failed to get sequence node"), + } +} + +#[test] +fn set_context_test_before_key_resolution_transition() { + let planner = planner!( + Subgraph1: r#" + type Query { + customer: Customer! + } + + type Identifiers @key(fields: "id") { + id: ID! + legacyUserId: ID! + } + + type Customer @key(fields: "id") { + id: ID! + child: Child! + identifiers: Identifiers! + } + + type Child @key(fields: "id") { + id: ID! + } + "#, + Subgraph2: r#" + type Customer @key(fields: "id") @context(name: "ctx") { + id: ID! + identifiers: Identifiers! @external + } + + type Identifiers @key(fields: "id") { + id: ID! + legacyUserId: ID! @external + } + + type Child @key(fields: "id") { + id: ID! + prop( + legacyUserId: ID + @fromContext(field: "$ctx { identifiers { legacyUserId } }") + ): String + } + "#, + ); + + assert_plan!(planner, + r#" + query { + customer { + child { + id + prop + } + } + } + "#, + @r###" + QueryPlan { + Sequence { + Fetch(service: "Subgraph1") { + { + customer { + __typename + identifiers { + legacyUserId + } + child { + __typename + id + } + } + } + }, + Flatten(path: "customer.child") { + Fetch(service: "Subgraph2") { + { + ... on Child { + __typename + id + } + } => + { + ... on Child { + prop(legacyUserId: $contextualArgument_1_0) + } + } + }, + }, + }, + } + "### + ); +} + +#[test] +fn set_context_test_efficiently_merge_fetch_groups() { + let planner = planner!( + Subgraph1: r#" + type Identifiers @key(fields: "id") { + id: ID! + id2: ID @external + id3: ID @external + wid: ID @requires(fields: "id2 id3") + } + "#, + Subgraph2: r#" + type Query { + customer: Customer + } + + type Customer @key(fields: "id") { + id: ID! + identifiers: Identifiers + mid: ID + } + + type Identifiers @key(fields: "id") { + id: ID! + id2: ID + id3: ID + id5: ID + } + "#, + Subgraph3: r#" + type Customer @key(fields: "id") @context(name: "retailCtx") { + accounts: Accounts @shareable + id: ID! + mid: ID @external + identifiers: Identifiers @external + } + + type Identifiers @key(fields: "id") { + id: ID! + id5: ID @external + } + type Accounts @key(fields: "id") { + foo( + randomInput: String + ctx_id5: ID + @fromContext(field: "$retailCtx { identifiers { id5 } }") + ctx_mid: ID @fromContext(field: "$retailCtx { mid }") + ): Foo + id: ID! + } + + type Foo { + id: ID + } + "#, + Subgraph4: r#" + type Customer + @key(fields: "id", resolvable: false) + @context(name: "widCtx") { + accounts: Accounts @shareable + id: ID! + identifiers: Identifiers @external + } + + type Identifiers @key(fields: "id", resolvable: false) { + id: ID! + wid: ID @external # @requires(fields: "id2 id3") + } + + type Accounts @key(fields: "id") { + bar( + ctx_wid: ID @fromContext(field: "$widCtx { identifiers { wid } }") + ): Bar + + id: ID! + } + + type Bar { + id: ID + } + "#, + ); + + let plan = assert_plan!(planner, + r#" + query { + customer { + accounts { + foo { + id + } + } + } + } + "#, + @r###" + QueryPlan { + Sequence { + Fetch(service: "Subgraph2") { + { + customer { + __typename + id + identifiers { + id5 + } + mid + } + } + }, + Flatten(path: "customer") { + Fetch(service: "Subgraph3") { + { + ... on Customer { + __typename + id + } + } => + { + ... on Customer { + accounts { + foo(ctx_id5: $contextualArgument_1_0, ctx_mid: $contextualArgument_1_1) { + id + } + } + } + } + }, + }, + }, + } + "### + ); + match plan.node { + Some(TopLevelPlanNode::Sequence(node)) => match node.nodes.get(1) { + Some(PlanNode::Flatten(node)) => match &*node.node { + PlanNode::Fetch(node) => { + assert_eq!( + node.context_rewrites, + vec![ + Arc::new(FetchDataRewrite::KeyRenamer(FetchDataKeyRenamer { + rename_key_to: Name::new("contextualArgument_1_0").unwrap(), + path: vec![ + FetchDataPathElement::Key( + Name::new_unchecked("identifiers"), + Default::default() + ), + FetchDataPathElement::Key( + Name::new_unchecked("id5"), + Default::default() + ), + ], + })), + Arc::new(FetchDataRewrite::KeyRenamer(FetchDataKeyRenamer { + rename_key_to: Name::new("contextualArgument_1_1").unwrap(), + path: vec![FetchDataPathElement::Key( + Name::new_unchecked("mid"), + Default::default() + ),], + })), + ] + ); + } + _ => panic!("failed to get fetch node"), + }, + _ => panic!("failed to get flatten node"), + }, + _ => panic!("failed to get sequence node"), + } +} diff --git a/apollo-federation/tests/query_plan/supergraphs/set_context_one_subgraph.graphql b/apollo-federation/tests/query_plan/supergraphs/set_context_one_subgraph.graphql new file mode 100644 index 0000000000..5a7c7ab74c --- /dev/null +++ b/apollo-federation/tests/query_plan/supergraphs/set_context_one_subgraph.graphql @@ -0,0 +1,87 @@ +# Composed from subgraphs with hash: 493d78ea411e0726dbfcd63da1534851ed24438d +schema + @link(url: "https://specs.apollo.dev/link/v1.0") + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) + @link(url: "https://specs.apollo.dev/context/v0.1", import: ["@context"], for: SECURITY) +{ + query: Query +} + +directive @context(name: String!) repeatable on INTERFACE | OBJECT | UNION + +directive @context__fromContext(field: context__ContextFieldValue) on ARGUMENT_DEFINITION + +directive @join__directive(graphs: [join__Graph!], name: String!, args: join__DirectiveArguments) repeatable on SCHEMA | OBJECT | INTERFACE | FIELD_DEFINITION + +directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE + +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + +directive @join__graph(name: String!, url: String!) on ENUM_VALUE + +directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE + +directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true, isInterfaceObject: Boolean! = false) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + +directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on UNION + +directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA + +scalar context__ContextFieldValue + +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + +scalar join__DirectiveArguments + +scalar join__FieldSet + +scalar join__FieldValue + +enum join__Graph { + SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") + SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") +} + +scalar link__Import + +enum link__Purpose { + """ + `SECURITY` features provide metadata necessary to securely resolve fields. + """ + SECURITY + + """ + `EXECUTION` features provide metadata necessary for operation execution. + """ + EXECUTION +} + +type Query + @join__type(graph: SUBGRAPH1) + @join__type(graph: SUBGRAPH2) +{ + t: T! @join__field(graph: SUBGRAPH1) + randomId: ID! @join__field(graph: SUBGRAPH2) +} + +type T + @join__type(graph: SUBGRAPH1, key: "id") + @context(name: "Subgraph1__context") +{ + id: ID! + u: U! + prop: String! +} + +type U + @join__type(graph: SUBGRAPH1, key: "id") +{ + id: ID! + b: String! + field: Int! @join__field(graph: SUBGRAPH1, contextArguments: [{context: "Subgraph1__context", name: "a", type: "String", selection: " { prop }"}]) +} diff --git a/apollo-federation/tests/query_plan/supergraphs/set_context_required_field_is_several_levels_deep_going_back_and_forth_between_subgraphs.graphql b/apollo-federation/tests/query_plan/supergraphs/set_context_required_field_is_several_levels_deep_going_back_and_forth_between_subgraphs.graphql new file mode 100644 index 0000000000..9fe87e18b6 --- /dev/null +++ b/apollo-federation/tests/query_plan/supergraphs/set_context_required_field_is_several_levels_deep_going_back_and_forth_between_subgraphs.graphql @@ -0,0 +1,110 @@ +# Composed from subgraphs with hash: f1dd07e720398727750d4546a6c36b1ee83e38d0 +schema + @link(url: "https://specs.apollo.dev/link/v1.0") + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) + @link(url: "https://specs.apollo.dev/context/v0.1", import: ["@context"], for: SECURITY) +{ + query: Query +} + +directive @context(name: String!) repeatable on INTERFACE | OBJECT | UNION + +directive @context__fromContext(field: context__ContextFieldValue) on ARGUMENT_DEFINITION + +directive @join__directive(graphs: [join__Graph!], name: String!, args: join__DirectiveArguments) repeatable on SCHEMA | OBJECT | INTERFACE | FIELD_DEFINITION + +directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE + +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + +directive @join__graph(name: String!, url: String!) on ENUM_VALUE + +directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE + +directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true, isInterfaceObject: Boolean! = false) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + +directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on UNION + +directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA + +type A + @join__type(graph: SUBGRAPH1, key: "id") + @join__type(graph: SUBGRAPH2, key: "id") +{ + id: ID! + b: B! @join__field(graph: SUBGRAPH1, external: true) @join__field(graph: SUBGRAPH2) +} + +type B + @join__type(graph: SUBGRAPH1, key: "id") + @join__type(graph: SUBGRAPH2, key: "id") +{ + id: ID! + c: C! @join__field(graph: SUBGRAPH1) +} + +type C + @join__type(graph: SUBGRAPH1, key: "id") +{ + id: ID! + prop: String! +} + +scalar context__ContextFieldValue + +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + +scalar join__DirectiveArguments + +scalar join__FieldSet + +scalar join__FieldValue + +enum join__Graph { + SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") + SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") +} + +scalar link__Import + +enum link__Purpose { + """ + `SECURITY` features provide metadata necessary to securely resolve fields. + """ + SECURITY + + """ + `EXECUTION` features provide metadata necessary for operation execution. + """ + EXECUTION +} + +type Query + @join__type(graph: SUBGRAPH1) + @join__type(graph: SUBGRAPH2) +{ + t: T! @join__field(graph: SUBGRAPH1) + randomId: ID! @join__field(graph: SUBGRAPH2) +} + +type T + @join__type(graph: SUBGRAPH1, key: "id") + @context(name: "Subgraph1__context") +{ + id: ID! + u: U! + a: A! +} + +type U + @join__type(graph: SUBGRAPH1, key: "id") +{ + id: ID! + b: String! + field: Int! @join__field(graph: SUBGRAPH1, contextArguments: [{context: "Subgraph1__context", name: "a", type: "String", selection: " { a { b { c { prop }}} }"}]) +} diff --git a/apollo-federation/tests/query_plan/supergraphs/set_context_test_accesses_a_different_top_level_query.graphql b/apollo-federation/tests/query_plan/supergraphs/set_context_test_accesses_a_different_top_level_query.graphql new file mode 100644 index 0000000000..c911771068 --- /dev/null +++ b/apollo-federation/tests/query_plan/supergraphs/set_context_test_accesses_a_different_top_level_query.graphql @@ -0,0 +1,87 @@ +# Composed from subgraphs with hash: ccebd26247c9c39723f64c9ed99609619a002604 +schema + @link(url: "https://specs.apollo.dev/link/v1.0") + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) + @link(url: "https://specs.apollo.dev/context/v0.1", import: ["@context"], for: SECURITY) +{ + query: Query +} + +directive @context(name: String!) repeatable on INTERFACE | OBJECT | UNION + +directive @context__fromContext(field: context__ContextFieldValue) on ARGUMENT_DEFINITION + +directive @join__directive(graphs: [join__Graph!], name: String!, args: join__DirectiveArguments) repeatable on SCHEMA | OBJECT | INTERFACE | FIELD_DEFINITION + +directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE + +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + +directive @join__graph(name: String!, url: String!) on ENUM_VALUE + +directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE + +directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true, isInterfaceObject: Boolean! = false) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + +directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on UNION + +directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA + +scalar context__ContextFieldValue + +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + +scalar join__DirectiveArguments + +scalar join__FieldSet + +scalar join__FieldValue + +enum join__Graph { + SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") + SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") +} + +scalar link__Import + +enum link__Purpose { + """ + `SECURITY` features provide metadata necessary to securely resolve fields. + """ + SECURITY + + """ + `EXECUTION` features provide metadata necessary for operation execution. + """ + EXECUTION +} + +type Product + @join__type(graph: SUBGRAPH1, key: "id") + @join__type(graph: SUBGRAPH2, key: "id") +{ + id: ID! + price: Int! @join__field(graph: SUBGRAPH1, contextArguments: [{context: "Subgraph1__topLevelQuery", name: "locale", type: "String", selection: " { me { locale } }"}]) +} + +type Query + @join__type(graph: SUBGRAPH1) + @join__type(graph: SUBGRAPH2) + @context(name: "Subgraph1__topLevelQuery") +{ + me: User! @join__field(graph: SUBGRAPH1) + product: Product @join__field(graph: SUBGRAPH1) + randomId: ID! @join__field(graph: SUBGRAPH2) +} + +type User + @join__type(graph: SUBGRAPH1, key: "id") +{ + id: ID! + locale: String! +} diff --git a/apollo-federation/tests/query_plan/supergraphs/set_context_test_before_key_resolution_transition.graphql b/apollo-federation/tests/query_plan/supergraphs/set_context_test_before_key_resolution_transition.graphql new file mode 100644 index 0000000000..496cc9fd8c --- /dev/null +++ b/apollo-federation/tests/query_plan/supergraphs/set_context_test_before_key_resolution_transition.graphql @@ -0,0 +1,95 @@ +# Composed from subgraphs with hash: 70f79d57f189ed5847e652ef9fa7c60603f2d639 +schema + @link(url: "https://specs.apollo.dev/link/v1.0") + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) + @link(url: "https://specs.apollo.dev/context/v0.1", import: ["@context"], for: SECURITY) +{ + query: Query +} + +directive @context(name: String!) repeatable on INTERFACE | OBJECT | UNION + +directive @context__fromContext(field: context__ContextFieldValue) on ARGUMENT_DEFINITION + +directive @join__directive(graphs: [join__Graph!], name: String!, args: join__DirectiveArguments) repeatable on SCHEMA | OBJECT | INTERFACE | FIELD_DEFINITION + +directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE + +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + +directive @join__graph(name: String!, url: String!) on ENUM_VALUE + +directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE + +directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true, isInterfaceObject: Boolean! = false) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + +directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on UNION + +directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA + +type Child + @join__type(graph: SUBGRAPH1, key: "id") + @join__type(graph: SUBGRAPH2, key: "id") +{ + id: ID! + prop: String @join__field(graph: SUBGRAPH2, contextArguments: [{context: "Subgraph2__ctx", name: "legacyUserId", type: "ID", selection: " { identifiers { legacyUserId } }"}]) +} + +scalar context__ContextFieldValue + +type Customer + @join__type(graph: SUBGRAPH1, key: "id") + @join__type(graph: SUBGRAPH2, key: "id") + @context(name: "Subgraph2__ctx") +{ + id: ID! + child: Child! @join__field(graph: SUBGRAPH1) + identifiers: Identifiers! @join__field(graph: SUBGRAPH1) @join__field(graph: SUBGRAPH2, external: true) +} + +type Identifiers + @join__type(graph: SUBGRAPH1, key: "id") + @join__type(graph: SUBGRAPH2, key: "id") +{ + id: ID! + legacyUserId: ID! @join__field(graph: SUBGRAPH1) @join__field(graph: SUBGRAPH2, external: true) +} + +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + +scalar join__DirectiveArguments + +scalar join__FieldSet + +scalar join__FieldValue + +enum join__Graph { + SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") + SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") +} + +scalar link__Import + +enum link__Purpose { + """ + `SECURITY` features provide metadata necessary to securely resolve fields. + """ + SECURITY + + """ + `EXECUTION` features provide metadata necessary for operation execution. + """ + EXECUTION +} + +type Query + @join__type(graph: SUBGRAPH1) + @join__type(graph: SUBGRAPH2) +{ + customer: Customer! @join__field(graph: SUBGRAPH1) +} diff --git a/apollo-federation/tests/query_plan/supergraphs/set_context_test_efficiently_merge_fetch_groups.graphql b/apollo-federation/tests/query_plan/supergraphs/set_context_test_efficiently_merge_fetch_groups.graphql new file mode 100644 index 0000000000..d0e79d42e3 --- /dev/null +++ b/apollo-federation/tests/query_plan/supergraphs/set_context_test_efficiently_merge_fetch_groups.graphql @@ -0,0 +1,120 @@ +# Composed from subgraphs with hash: 753d6866862484ee27a265b4f2f2f9d4e0c97b03 +schema + @link(url: "https://specs.apollo.dev/link/v1.0") + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) + @link(url: "https://specs.apollo.dev/context/v0.1", import: ["@context"], for: SECURITY) +{ + query: Query +} + +directive @context(name: String!) repeatable on INTERFACE | OBJECT | UNION + +directive @context__fromContext(field: context__ContextFieldValue) on ARGUMENT_DEFINITION + +directive @join__directive(graphs: [join__Graph!], name: String!, args: join__DirectiveArguments) repeatable on SCHEMA | OBJECT | INTERFACE | FIELD_DEFINITION + +directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE + +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + +directive @join__graph(name: String!, url: String!) on ENUM_VALUE + +directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE + +directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true, isInterfaceObject: Boolean! = false) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + +directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on UNION + +directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA + +type Accounts + @join__type(graph: SUBGRAPH3, key: "id") + @join__type(graph: SUBGRAPH4, key: "id") +{ + foo(randomInput: String): Foo @join__field(graph: SUBGRAPH3, contextArguments: [{context: "Subgraph3__retailCtx", name: "ctx_id5", type: "ID", selection: " { identifiers { id5 } }"}, {context: "Subgraph3__retailCtx", name: "ctx_mid", type: "ID", selection: " { mid }"}]) + id: ID! + bar: Bar @join__field(graph: SUBGRAPH4, contextArguments: [{context: "Subgraph4__widCtx", name: "ctx_wid", type: "ID", selection: " { identifiers { wid } }"}]) +} + +type Bar + @join__type(graph: SUBGRAPH4) +{ + id: ID +} + +scalar context__ContextFieldValue + +type Customer + @join__type(graph: SUBGRAPH2, key: "id") + @join__type(graph: SUBGRAPH3, key: "id") + @join__type(graph: SUBGRAPH4, key: "id", resolvable: false) + @context(name: "Subgraph3__retailCtx") + @context(name: "Subgraph4__widCtx") +{ + id: ID! + identifiers: Identifiers @join__field(graph: SUBGRAPH2) @join__field(graph: SUBGRAPH3, external: true) @join__field(graph: SUBGRAPH4, external: true) + mid: ID @join__field(graph: SUBGRAPH2) @join__field(graph: SUBGRAPH3, external: true) + accounts: Accounts @join__field(graph: SUBGRAPH3) @join__field(graph: SUBGRAPH4) +} + +type Foo + @join__type(graph: SUBGRAPH3) +{ + id: ID +} + +type Identifiers + @join__type(graph: SUBGRAPH1, key: "id") + @join__type(graph: SUBGRAPH2, key: "id") + @join__type(graph: SUBGRAPH3, key: "id") + @join__type(graph: SUBGRAPH4, key: "id", resolvable: false) +{ + id: ID! + id2: ID @join__field(graph: SUBGRAPH1, external: true) @join__field(graph: SUBGRAPH2) + id3: ID @join__field(graph: SUBGRAPH1, external: true) @join__field(graph: SUBGRAPH2) + wid: ID @join__field(graph: SUBGRAPH1, requires: "id2 id3") @join__field(graph: SUBGRAPH4, external: true) + id5: ID @join__field(graph: SUBGRAPH2) @join__field(graph: SUBGRAPH3, external: true) +} + +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + +scalar join__DirectiveArguments + +scalar join__FieldSet + +scalar join__FieldValue + +enum join__Graph { + SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") + SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") + SUBGRAPH3 @join__graph(name: "Subgraph3", url: "none") + SUBGRAPH4 @join__graph(name: "Subgraph4", url: "none") +} + +scalar link__Import + +enum link__Purpose { + """ + `SECURITY` features provide metadata necessary to securely resolve fields. + """ + SECURITY + + """ + `EXECUTION` features provide metadata necessary for operation execution. + """ + EXECUTION +} + +type Query + @join__type(graph: SUBGRAPH1) + @join__type(graph: SUBGRAPH2) + @join__type(graph: SUBGRAPH3) + @join__type(graph: SUBGRAPH4) +{ + customer: Customer @join__field(graph: SUBGRAPH2) +} diff --git a/apollo-federation/tests/query_plan/supergraphs/set_context_test_fetched_as_a_list.graphql b/apollo-federation/tests/query_plan/supergraphs/set_context_test_fetched_as_a_list.graphql new file mode 100644 index 0000000000..354ae88c1c --- /dev/null +++ b/apollo-federation/tests/query_plan/supergraphs/set_context_test_fetched_as_a_list.graphql @@ -0,0 +1,88 @@ +# Composed from subgraphs with hash: 8b81d5086b71ff9fb618f2d250eec4b47f7a1d04 +schema + @link(url: "https://specs.apollo.dev/link/v1.0") + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) + @link(url: "https://specs.apollo.dev/context/v0.1", import: ["@context"], for: SECURITY) +{ + query: Query +} + +directive @context(name: String!) repeatable on INTERFACE | OBJECT | UNION + +directive @context__fromContext(field: context__ContextFieldValue) on ARGUMENT_DEFINITION + +directive @join__directive(graphs: [join__Graph!], name: String!, args: join__DirectiveArguments) repeatable on SCHEMA | OBJECT | INTERFACE | FIELD_DEFINITION + +directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE + +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + +directive @join__graph(name: String!, url: String!) on ENUM_VALUE + +directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE + +directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true, isInterfaceObject: Boolean! = false) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + +directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on UNION + +directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA + +scalar context__ContextFieldValue + +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + +scalar join__DirectiveArguments + +scalar join__FieldSet + +scalar join__FieldValue + +enum join__Graph { + SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") + SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") +} + +scalar link__Import + +enum link__Purpose { + """ + `SECURITY` features provide metadata necessary to securely resolve fields. + """ + SECURITY + + """ + `EXECUTION` features provide metadata necessary for operation execution. + """ + EXECUTION +} + +type Query + @join__type(graph: SUBGRAPH1) + @join__type(graph: SUBGRAPH2) +{ + t: [T]! @join__field(graph: SUBGRAPH1) + a: Int! @join__field(graph: SUBGRAPH2) +} + +type T + @join__type(graph: SUBGRAPH1, key: "id") + @context(name: "Subgraph1__context") +{ + id: ID! + u: U! + prop: String! +} + +type U + @join__type(graph: SUBGRAPH1, key: "id") + @join__type(graph: SUBGRAPH2, key: "id") +{ + id: ID! + b: String! @join__field(graph: SUBGRAPH1) + field: Int! @join__field(graph: SUBGRAPH1, contextArguments: [{context: "Subgraph1__context", name: "a", type: "String", selection: " { prop }"}]) +} diff --git a/apollo-federation/tests/query_plan/supergraphs/set_context_test_impacts_on_query_planning.graphql b/apollo-federation/tests/query_plan/supergraphs/set_context_test_impacts_on_query_planning.graphql new file mode 100644 index 0000000000..596c21edad --- /dev/null +++ b/apollo-federation/tests/query_plan/supergraphs/set_context_test_impacts_on_query_planning.graphql @@ -0,0 +1,106 @@ +# Composed from subgraphs with hash: 173623d59b042e5f8dcf81f5c08880ad2d2d3ccb +schema + @link(url: "https://specs.apollo.dev/link/v1.0") + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) + @link(url: "https://specs.apollo.dev/context/v0.1", import: ["@context"], for: SECURITY) +{ + query: Query +} + +directive @context(name: String!) repeatable on INTERFACE | OBJECT | UNION + +directive @context__fromContext(field: context__ContextFieldValue) on ARGUMENT_DEFINITION + +directive @join__directive(graphs: [join__Graph!], name: String!, args: join__DirectiveArguments) repeatable on SCHEMA | OBJECT | INTERFACE | FIELD_DEFINITION + +directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE + +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + +directive @join__graph(name: String!, url: String!) on ENUM_VALUE + +directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE + +directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true, isInterfaceObject: Boolean! = false) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + +directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on UNION + +directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA + +type A implements I + @join__implements(graph: SUBGRAPH1, interface: "I") + @join__type(graph: SUBGRAPH1, key: "id") +{ + id: ID! + u: U! + prop: String! +} + +type B implements I + @join__implements(graph: SUBGRAPH1, interface: "I") + @join__type(graph: SUBGRAPH1, key: "id") +{ + id: ID! + u: U! + prop: String! +} + +scalar context__ContextFieldValue + +interface I + @join__type(graph: SUBGRAPH1, key: "id") + @context(name: "Subgraph1__context") +{ + id: ID! + u: U! + prop: String! +} + +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + +scalar join__DirectiveArguments + +scalar join__FieldSet + +scalar join__FieldValue + +enum join__Graph { + SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") + SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") +} + +scalar link__Import + +enum link__Purpose { + """ + `SECURITY` features provide metadata necessary to securely resolve fields. + """ + SECURITY + + """ + `EXECUTION` features provide metadata necessary for operation execution. + """ + EXECUTION +} + +type Query + @join__type(graph: SUBGRAPH1) + @join__type(graph: SUBGRAPH2) +{ + t: I! @join__field(graph: SUBGRAPH1) + a: Int! @join__field(graph: SUBGRAPH2) +} + +type U + @join__type(graph: SUBGRAPH1, key: "id") + @join__type(graph: SUBGRAPH2, key: "id") +{ + id: ID! + b: String! @join__field(graph: SUBGRAPH1) + field: Int! @join__field(graph: SUBGRAPH1, contextArguments: [{context: "Subgraph1__context", name: "a", type: "String", selection: " { prop }"}]) +} diff --git a/apollo-federation/tests/query_plan/supergraphs/set_context_test_variable_is_a_list.graphql b/apollo-federation/tests/query_plan/supergraphs/set_context_test_variable_is_a_list.graphql new file mode 100644 index 0000000000..d502c7d4b1 --- /dev/null +++ b/apollo-federation/tests/query_plan/supergraphs/set_context_test_variable_is_a_list.graphql @@ -0,0 +1,87 @@ +# Composed from subgraphs with hash: 1a8895fe791cc7cd69ace02dc95527034d7d864f +schema + @link(url: "https://specs.apollo.dev/link/v1.0") + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) + @link(url: "https://specs.apollo.dev/context/v0.1", import: ["@context"], for: SECURITY) +{ + query: Query +} + +directive @context(name: String!) repeatable on INTERFACE | OBJECT | UNION + +directive @context__fromContext(field: context__ContextFieldValue) on ARGUMENT_DEFINITION + +directive @join__directive(graphs: [join__Graph!], name: String!, args: join__DirectiveArguments) repeatable on SCHEMA | OBJECT | INTERFACE | FIELD_DEFINITION + +directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE + +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + +directive @join__graph(name: String!, url: String!) on ENUM_VALUE + +directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE + +directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true, isInterfaceObject: Boolean! = false) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + +directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on UNION + +directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA + +scalar context__ContextFieldValue + +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + +scalar join__DirectiveArguments + +scalar join__FieldSet + +scalar join__FieldValue + +enum join__Graph { + SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") + SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") +} + +scalar link__Import + +enum link__Purpose { + """ + `SECURITY` features provide metadata necessary to securely resolve fields. + """ + SECURITY + + """ + `EXECUTION` features provide metadata necessary for operation execution. + """ + EXECUTION +} + +type Query + @join__type(graph: SUBGRAPH1) + @join__type(graph: SUBGRAPH2) +{ + t: T! @join__field(graph: SUBGRAPH1) + a: Int! @join__field(graph: SUBGRAPH2) +} + +type T + @join__type(graph: SUBGRAPH1, key: "id") + @context(name: "Subgraph1__context") +{ + id: ID! + u: U! + prop: [String]! +} + +type U + @join__type(graph: SUBGRAPH1, key: "id") + @join__type(graph: SUBGRAPH2, key: "id") +{ + id: ID! + field: Int! @join__field(graph: SUBGRAPH1, contextArguments: [{context: "Subgraph1__context", name: "a", type: "[String]", selection: " { prop }"}]) +} diff --git a/apollo-federation/tests/query_plan/supergraphs/set_context_test_variable_is_already_in_a_different_fetch_group.graphql b/apollo-federation/tests/query_plan/supergraphs/set_context_test_variable_is_already_in_a_different_fetch_group.graphql new file mode 100644 index 0000000000..55fbffc7dd --- /dev/null +++ b/apollo-federation/tests/query_plan/supergraphs/set_context_test_variable_is_already_in_a_different_fetch_group.graphql @@ -0,0 +1,88 @@ +# Composed from subgraphs with hash: 295947c45a4fbf129c3112e24611d04c40619c86 +schema + @link(url: "https://specs.apollo.dev/link/v1.0") + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) + @link(url: "https://specs.apollo.dev/context/v0.1", import: ["@context"], for: SECURITY) +{ + query: Query +} + +directive @context(name: String!) repeatable on INTERFACE | OBJECT | UNION + +directive @context__fromContext(field: context__ContextFieldValue) on ARGUMENT_DEFINITION + +directive @join__directive(graphs: [join__Graph!], name: String!, args: join__DirectiveArguments) repeatable on SCHEMA | OBJECT | INTERFACE | FIELD_DEFINITION + +directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE + +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + +directive @join__graph(name: String!, url: String!) on ENUM_VALUE + +directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE + +directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true, isInterfaceObject: Boolean! = false) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + +directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on UNION + +directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA + +scalar context__ContextFieldValue + +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + +scalar join__DirectiveArguments + +scalar join__FieldSet + +scalar join__FieldValue + +enum join__Graph { + SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") + SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") +} + +scalar link__Import + +enum link__Purpose { + """ + `SECURITY` features provide metadata necessary to securely resolve fields. + """ + SECURITY + + """ + `EXECUTION` features provide metadata necessary for operation execution. + """ + EXECUTION +} + +type Query + @join__type(graph: SUBGRAPH1) + @join__type(graph: SUBGRAPH2) +{ + t: T! @join__field(graph: SUBGRAPH1) + a: Int! @join__field(graph: SUBGRAPH2) +} + +type T + @join__type(graph: SUBGRAPH1, key: "id") + @join__type(graph: SUBGRAPH2, key: "id") + @context(name: "Subgraph2__context") +{ + id: ID! + u: U! @join__field(graph: SUBGRAPH1) + prop: String! @join__field(graph: SUBGRAPH1) @join__field(graph: SUBGRAPH2, external: true) +} + +type U + @join__type(graph: SUBGRAPH1, key: "id") + @join__type(graph: SUBGRAPH2, key: "id") +{ + id: ID! + field: Int! @join__field(graph: SUBGRAPH2, contextArguments: [{context: "Subgraph2__context", name: "a", type: "String", selection: " { prop }"}]) +} diff --git a/apollo-federation/tests/query_plan/supergraphs/set_context_test_variable_is_from_different_subgraph.graphql b/apollo-federation/tests/query_plan/supergraphs/set_context_test_variable_is_from_different_subgraph.graphql new file mode 100644 index 0000000000..f71c83f1a3 --- /dev/null +++ b/apollo-federation/tests/query_plan/supergraphs/set_context_test_variable_is_from_different_subgraph.graphql @@ -0,0 +1,88 @@ +# Composed from subgraphs with hash: a1eeaafd2a79733109742acf5e08df586d1358b0 +schema + @link(url: "https://specs.apollo.dev/link/v1.0") + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) + @link(url: "https://specs.apollo.dev/context/v0.1", import: ["@context"], for: SECURITY) +{ + query: Query +} + +directive @context(name: String!) repeatable on INTERFACE | OBJECT | UNION + +directive @context__fromContext(field: context__ContextFieldValue) on ARGUMENT_DEFINITION + +directive @join__directive(graphs: [join__Graph!], name: String!, args: join__DirectiveArguments) repeatable on SCHEMA | OBJECT | INTERFACE | FIELD_DEFINITION + +directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE + +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + +directive @join__graph(name: String!, url: String!) on ENUM_VALUE + +directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE + +directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true, isInterfaceObject: Boolean! = false) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + +directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on UNION + +directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA + +scalar context__ContextFieldValue + +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + +scalar join__DirectiveArguments + +scalar join__FieldSet + +scalar join__FieldValue + +enum join__Graph { + SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") + SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") +} + +scalar link__Import + +enum link__Purpose { + """ + `SECURITY` features provide metadata necessary to securely resolve fields. + """ + SECURITY + + """ + `EXECUTION` features provide metadata necessary for operation execution. + """ + EXECUTION +} + +type Query + @join__type(graph: SUBGRAPH1) + @join__type(graph: SUBGRAPH2) +{ + t: T! @join__field(graph: SUBGRAPH1) + a: Int! @join__field(graph: SUBGRAPH2) +} + +type T + @join__type(graph: SUBGRAPH1, key: "id") + @join__type(graph: SUBGRAPH2, key: "id") + @context(name: "Subgraph1__context") +{ + id: ID! + u: U! @join__field(graph: SUBGRAPH1) + prop: String! @join__field(graph: SUBGRAPH1, external: true) @join__field(graph: SUBGRAPH2) +} + +type U + @join__type(graph: SUBGRAPH1, key: "id") + @join__type(graph: SUBGRAPH2, key: "id") +{ + id: ID! + field: Int! @join__field(graph: SUBGRAPH1, contextArguments: [{context: "Subgraph1__context", name: "a", type: "String", selection: " { prop }"}]) +} diff --git a/apollo-federation/tests/query_plan/supergraphs/set_context_test_variable_is_from_same_subgraph.graphql b/apollo-federation/tests/query_plan/supergraphs/set_context_test_variable_is_from_same_subgraph.graphql new file mode 100644 index 0000000000..24d777888d --- /dev/null +++ b/apollo-federation/tests/query_plan/supergraphs/set_context_test_variable_is_from_same_subgraph.graphql @@ -0,0 +1,88 @@ +# Composed from subgraphs with hash: 2de3c6cc9b36392a362af0d19e03688085e2119b +schema + @link(url: "https://specs.apollo.dev/link/v1.0") + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) + @link(url: "https://specs.apollo.dev/context/v0.1", import: ["@context"], for: SECURITY) +{ + query: Query +} + +directive @context(name: String!) repeatable on INTERFACE | OBJECT | UNION + +directive @context__fromContext(field: context__ContextFieldValue) on ARGUMENT_DEFINITION + +directive @join__directive(graphs: [join__Graph!], name: String!, args: join__DirectiveArguments) repeatable on SCHEMA | OBJECT | INTERFACE | FIELD_DEFINITION + +directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE + +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + +directive @join__graph(name: String!, url: String!) on ENUM_VALUE + +directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE + +directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true, isInterfaceObject: Boolean! = false) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + +directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on UNION + +directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA + +scalar context__ContextFieldValue + +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + +scalar join__DirectiveArguments + +scalar join__FieldSet + +scalar join__FieldValue + +enum join__Graph { + SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") + SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") +} + +scalar link__Import + +enum link__Purpose { + """ + `SECURITY` features provide metadata necessary to securely resolve fields. + """ + SECURITY + + """ + `EXECUTION` features provide metadata necessary for operation execution. + """ + EXECUTION +} + +type Query + @join__type(graph: SUBGRAPH1) + @join__type(graph: SUBGRAPH2) +{ + t: T! @join__field(graph: SUBGRAPH1) + a: Int! @join__field(graph: SUBGRAPH2) +} + +type T + @join__type(graph: SUBGRAPH1, key: "id") + @context(name: "Subgraph1__context") +{ + id: ID! + u: U! + prop: String! +} + +type U + @join__type(graph: SUBGRAPH1, key: "id") + @join__type(graph: SUBGRAPH2, key: "id") +{ + id: ID! + b: String! @join__field(graph: SUBGRAPH1) + field: Int! @join__field(graph: SUBGRAPH1, contextArguments: [{context: "Subgraph1__context", name: "a", type: "String", selection: " { prop }"}]) +} diff --git a/apollo-federation/tests/query_plan/supergraphs/set_context_test_with_type_conditions_for_union.graphql b/apollo-federation/tests/query_plan/supergraphs/set_context_test_with_type_conditions_for_union.graphql new file mode 100644 index 0000000000..ae73fa590c --- /dev/null +++ b/apollo-federation/tests/query_plan/supergraphs/set_context_test_with_type_conditions_for_union.graphql @@ -0,0 +1,102 @@ +# Composed from subgraphs with hash: 0981934ba0944ccff6a8c554bef807ca905ad13a +schema + @link(url: "https://specs.apollo.dev/link/v1.0") + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) + @link(url: "https://specs.apollo.dev/context/v0.1", import: ["@context"], for: SECURITY) +{ + query: Query +} + +directive @context(name: String!) repeatable on INTERFACE | OBJECT | UNION + +directive @context__fromContext(field: context__ContextFieldValue) on ARGUMENT_DEFINITION + +directive @join__directive(graphs: [join__Graph!], name: String!, args: join__DirectiveArguments) repeatable on SCHEMA | OBJECT | INTERFACE | FIELD_DEFINITION + +directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE + +directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String, contextArguments: [join__ContextArgument!]) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + +directive @join__graph(name: String!, url: String!) on ENUM_VALUE + +directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE + +directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true, isInterfaceObject: Boolean! = false) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + +directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on UNION + +directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA + +type A + @join__type(graph: SUBGRAPH1, key: "id") +{ + id: ID! + u: U! + prop: String! +} + +type B + @join__type(graph: SUBGRAPH1, key: "id") +{ + id: ID! + u: U! + prop: String! +} + +scalar context__ContextFieldValue + +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + +scalar join__DirectiveArguments + +scalar join__FieldSet + +scalar join__FieldValue + +enum join__Graph { + SUBGRAPH1 @join__graph(name: "Subgraph1", url: "none") + SUBGRAPH2 @join__graph(name: "Subgraph2", url: "none") +} + +scalar link__Import + +enum link__Purpose { + """ + `SECURITY` features provide metadata necessary to securely resolve fields. + """ + SECURITY + + """ + `EXECUTION` features provide metadata necessary for operation execution. + """ + EXECUTION +} + +type Query + @join__type(graph: SUBGRAPH1) + @join__type(graph: SUBGRAPH2) +{ + t: T! @join__field(graph: SUBGRAPH1) + a: Int! @join__field(graph: SUBGRAPH2) +} + +union T + @join__type(graph: SUBGRAPH1) + @join__unionMember(graph: SUBGRAPH1, member: "A") + @join__unionMember(graph: SUBGRAPH1, member: "B") + @context(name: "Subgraph1__context") + = A | B + +type U + @join__type(graph: SUBGRAPH1, key: "id") + @join__type(graph: SUBGRAPH2, key: "id") +{ + id: ID! + b: String! @join__field(graph: SUBGRAPH1) + field: Int! @join__field(graph: SUBGRAPH1, contextArguments: [{context: "Subgraph1__context", name: "a", type: "String", selection: " ... on A { prop } ... on B { prop }"}]) +} diff --git a/apollo-federation/tests/snapshots/main__extract_subgraphs__can_extract_subgraph.snap b/apollo-federation/tests/snapshots/main__extract_subgraphs__can_extract_subgraph.snap index 324709bd56..50474161ef 100644 --- a/apollo-federation/tests/snapshots/main__extract_subgraphs__can_extract_subgraph.snap +++ b/apollo-federation/tests/snapshots/main__extract_subgraphs__can_extract_subgraph.snap @@ -42,6 +42,10 @@ directive @federation__cost(weight: Int!) on ARGUMENT_DEFINITION | ENUM | FIELD_ directive @federation__listSize(assumedSize: Int, slicingArguments: [String!], sizedFields: [String!], requireOneSlicingArgument: Boolean = true) on FIELD_DEFINITION +directive @federation__fromContext(field: String) on ARGUMENT_DEFINITION + +directive @federation__context(name: String) repeatable on INTERFACE | OBJECT | UNION + scalar link__Import enum link__Purpose { @@ -123,6 +127,10 @@ directive @federation__cost(weight: Int!) on ARGUMENT_DEFINITION | ENUM | FIELD_ directive @federation__listSize(assumedSize: Int, slicingArguments: [String!], sizedFields: [String!], requireOneSlicingArgument: Boolean = true) on FIELD_DEFINITION +directive @federation__fromContext(field: String) on ARGUMENT_DEFINITION + +directive @federation__context(name: String) repeatable on INTERFACE | OBJECT | UNION + scalar link__Import enum link__Purpose { diff --git a/apollo-federation/tests/snapshots/main__extract_subgraphs__does_not_extract_demand_control_directive_name_conflicts.snap b/apollo-federation/tests/snapshots/main__extract_subgraphs__does_not_extract_demand_control_directive_name_conflicts.snap index f86e759fca..a20ce0e66d 100644 --- a/apollo-federation/tests/snapshots/main__extract_subgraphs__does_not_extract_demand_control_directive_name_conflicts.snap +++ b/apollo-federation/tests/snapshots/main__extract_subgraphs__does_not_extract_demand_control_directive_name_conflicts.snap @@ -42,6 +42,10 @@ directive @federation__cost(weight: Int!) on ARGUMENT_DEFINITION | ENUM | FIELD_ directive @federation__listSize(assumedSize: Int, slicingArguments: [String!], sizedFields: [String!], requireOneSlicingArgument: Boolean = true) on FIELD_DEFINITION +directive @federation__fromContext(field: String) on ARGUMENT_DEFINITION + +directive @federation__context(name: String) repeatable on INTERFACE | OBJECT | UNION + scalar link__Import enum link__Purpose { @@ -112,6 +116,10 @@ directive @federation__cost(weight: Int!) on ARGUMENT_DEFINITION | ENUM | FIELD_ directive @federation__listSize(assumedSize: Int, slicingArguments: [String!], sizedFields: [String!], requireOneSlicingArgument: Boolean = true) on FIELD_DEFINITION +directive @federation__fromContext(field: String) on ARGUMENT_DEFINITION + +directive @federation__context(name: String) repeatable on INTERFACE | OBJECT | UNION + scalar link__Import enum link__Purpose { diff --git a/apollo-federation/tests/snapshots/main__extract_subgraphs__does_not_extract_renamed_demand_control_directive_name_conflicts.snap b/apollo-federation/tests/snapshots/main__extract_subgraphs__does_not_extract_renamed_demand_control_directive_name_conflicts.snap index f86e759fca..a20ce0e66d 100644 --- a/apollo-federation/tests/snapshots/main__extract_subgraphs__does_not_extract_renamed_demand_control_directive_name_conflicts.snap +++ b/apollo-federation/tests/snapshots/main__extract_subgraphs__does_not_extract_renamed_demand_control_directive_name_conflicts.snap @@ -42,6 +42,10 @@ directive @federation__cost(weight: Int!) on ARGUMENT_DEFINITION | ENUM | FIELD_ directive @federation__listSize(assumedSize: Int, slicingArguments: [String!], sizedFields: [String!], requireOneSlicingArgument: Boolean = true) on FIELD_DEFINITION +directive @federation__fromContext(field: String) on ARGUMENT_DEFINITION + +directive @federation__context(name: String) repeatable on INTERFACE | OBJECT | UNION + scalar link__Import enum link__Purpose { @@ -112,6 +116,10 @@ directive @federation__cost(weight: Int!) on ARGUMENT_DEFINITION | ENUM | FIELD_ directive @federation__listSize(assumedSize: Int, slicingArguments: [String!], sizedFields: [String!], requireOneSlicingArgument: Boolean = true) on FIELD_DEFINITION +directive @federation__fromContext(field: String) on ARGUMENT_DEFINITION + +directive @federation__context(name: String) repeatable on INTERFACE | OBJECT | UNION + scalar link__Import enum link__Purpose { diff --git a/apollo-federation/tests/snapshots/main__extract_subgraphs__extracts_demand_control_directives.snap b/apollo-federation/tests/snapshots/main__extract_subgraphs__extracts_demand_control_directives.snap index 319b91d908..c32e8c73a9 100644 --- a/apollo-federation/tests/snapshots/main__extract_subgraphs__extracts_demand_control_directives.snap +++ b/apollo-federation/tests/snapshots/main__extract_subgraphs__extracts_demand_control_directives.snap @@ -42,6 +42,10 @@ directive @federation__cost(weight: Int!) on ARGUMENT_DEFINITION | ENUM | FIELD_ directive @federation__listSize(assumedSize: Int, slicingArguments: [String!], sizedFields: [String!], requireOneSlicingArgument: Boolean = true) on FIELD_DEFINITION +directive @federation__fromContext(field: String) on ARGUMENT_DEFINITION + +directive @federation__context(name: String) repeatable on INTERFACE | OBJECT | UNION + scalar link__Import enum link__Purpose { @@ -132,6 +136,10 @@ directive @federation__cost(weight: Int!) on ARGUMENT_DEFINITION | ENUM | FIELD_ directive @federation__listSize(assumedSize: Int, slicingArguments: [String!], sizedFields: [String!], requireOneSlicingArgument: Boolean = true) on FIELD_DEFINITION +directive @federation__fromContext(field: String) on ARGUMENT_DEFINITION + +directive @federation__context(name: String) repeatable on INTERFACE | OBJECT | UNION + scalar link__Import enum link__Purpose { diff --git a/apollo-federation/tests/snapshots/main__extract_subgraphs__extracts_renamed_demand_control_directives.snap b/apollo-federation/tests/snapshots/main__extract_subgraphs__extracts_renamed_demand_control_directives.snap index 319b91d908..c32e8c73a9 100644 --- a/apollo-federation/tests/snapshots/main__extract_subgraphs__extracts_renamed_demand_control_directives.snap +++ b/apollo-federation/tests/snapshots/main__extract_subgraphs__extracts_renamed_demand_control_directives.snap @@ -42,6 +42,10 @@ directive @federation__cost(weight: Int!) on ARGUMENT_DEFINITION | ENUM | FIELD_ directive @federation__listSize(assumedSize: Int, slicingArguments: [String!], sizedFields: [String!], requireOneSlicingArgument: Boolean = true) on FIELD_DEFINITION +directive @federation__fromContext(field: String) on ARGUMENT_DEFINITION + +directive @federation__context(name: String) repeatable on INTERFACE | OBJECT | UNION + scalar link__Import enum link__Purpose { @@ -132,6 +136,10 @@ directive @federation__cost(weight: Int!) on ARGUMENT_DEFINITION | ENUM | FIELD_ directive @federation__listSize(assumedSize: Int, slicingArguments: [String!], sizedFields: [String!], requireOneSlicingArgument: Boolean = true) on FIELD_DEFINITION +directive @federation__fromContext(field: String) on ARGUMENT_DEFINITION + +directive @federation__context(name: String) repeatable on INTERFACE | OBJECT | UNION + scalar link__Import enum link__Purpose { diff --git a/apollo-federation/tests/snapshots/main__extract_subgraphs__extracts_set_context_directives.snap b/apollo-federation/tests/snapshots/main__extract_subgraphs__extracts_set_context_directives.snap new file mode 100644 index 0000000000..fd7c25bff1 --- /dev/null +++ b/apollo-federation/tests/snapshots/main__extract_subgraphs__extracts_set_context_directives.snap @@ -0,0 +1,170 @@ +--- +source: apollo-federation/tests/extract_subgraphs.rs +expression: snapshot +--- +Subgraph1 +--- +schema { + query: Query +} + +extend schema @link(url: "https://specs.apollo.dev/link/v1.0") @link(url: "https://specs.apollo.dev/federation/v2.9") + +directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA + +directive @federation__key(fields: federation__FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE + +directive @federation__requires(fields: federation__FieldSet!) on FIELD_DEFINITION + +directive @federation__provides(fields: federation__FieldSet!) on FIELD_DEFINITION + +directive @federation__external(reason: String) on OBJECT | FIELD_DEFINITION + +directive @federation__tag(name: String!) repeatable on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION | SCHEMA + +directive @federation__extends on OBJECT | INTERFACE + +directive @federation__shareable on OBJECT | FIELD_DEFINITION + +directive @federation__inaccessible on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION + +directive @federation__override(from: String!, label: String) on FIELD_DEFINITION + +directive @federation__composeDirective(name: String) repeatable on SCHEMA + +directive @federation__interfaceObject on OBJECT + +directive @federation__authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM + +directive @federation__requiresScopes(scopes: [[federation__Scope!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM + +directive @federation__cost(weight: Int!) on ARGUMENT_DEFINITION | ENUM | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | OBJECT | SCALAR + +directive @federation__listSize(assumedSize: Int, slicingArguments: [String!], sizedFields: [String!], requireOneSlicingArgument: Boolean = true) on FIELD_DEFINITION + +directive @federation__fromContext(field: String) on ARGUMENT_DEFINITION + +directive @federation__context(name: String) repeatable on INTERFACE | OBJECT | UNION + +scalar link__Import + +enum link__Purpose { + """ + \`SECURITY\` features provide metadata necessary to securely resolve fields. + """ + SECURITY + """ + \`EXECUTION\` features provide metadata necessary for operation execution. + """ + EXECUTION +} + +scalar federation__FieldSet + +scalar federation__Scope + +type Query { + t: T! + _entities(representations: [_Any!]!): [_Entity]! + _service: _Service! +} + +type T @federation__key(fields: "id", resolvable: true) @federation__context(name: "context") { + id: ID! + u: U! + prop: String! +} + +type U @federation__key(fields: "id", resolvable: true) { + id: ID! @federation__shareable + field( + a: String @federation__fromContext(field: "$context { prop }"), + ): Int! +} + +scalar _Any + +type _Service { + sdl: String +} + +union _Entity = T | U + +Subgraph2 +--- +schema { + query: Query +} + +extend schema @link(url: "https://specs.apollo.dev/link/v1.0") @link(url: "https://specs.apollo.dev/federation/v2.9") + +directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA + +directive @federation__key(fields: federation__FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE + +directive @federation__requires(fields: federation__FieldSet!) on FIELD_DEFINITION + +directive @federation__provides(fields: federation__FieldSet!) on FIELD_DEFINITION + +directive @federation__external(reason: String) on OBJECT | FIELD_DEFINITION + +directive @federation__tag(name: String!) repeatable on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION | SCHEMA + +directive @federation__extends on OBJECT | INTERFACE + +directive @federation__shareable on OBJECT | FIELD_DEFINITION + +directive @federation__inaccessible on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION + +directive @federation__override(from: String!, label: String) on FIELD_DEFINITION + +directive @federation__composeDirective(name: String) repeatable on SCHEMA + +directive @federation__interfaceObject on OBJECT + +directive @federation__authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM + +directive @federation__requiresScopes(scopes: [[federation__Scope!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM + +directive @federation__cost(weight: Int!) on ARGUMENT_DEFINITION | ENUM | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | OBJECT | SCALAR + +directive @federation__listSize(assumedSize: Int, slicingArguments: [String!], sizedFields: [String!], requireOneSlicingArgument: Boolean = true) on FIELD_DEFINITION + +directive @federation__fromContext(field: String) on ARGUMENT_DEFINITION + +directive @federation__context(name: String) repeatable on INTERFACE | OBJECT | UNION + +scalar link__Import + +enum link__Purpose { + """ + \`SECURITY\` features provide metadata necessary to securely resolve fields. + """ + SECURITY + """ + \`EXECUTION\` features provide metadata necessary for operation execution. + """ + EXECUTION +} + +scalar federation__FieldSet + +scalar federation__Scope + +type Query { + a: Int! + _entities(representations: [_Any!]!): [_Entity]! + _service: _Service! +} + +type U @federation__key(fields: "id", resolvable: true) { + id: ID! @federation__shareable +} + +scalar _Any + +type _Service { + sdl: String +} + +union _Entity = U diff --git a/apollo-router/src/json_ext.rs b/apollo-router/src/json_ext.rs index 9bc94833d0..81423deb8b 100644 --- a/apollo-router/src/json_ext.rs +++ b/apollo-router/src/json_ext.rs @@ -155,9 +155,6 @@ pub(crate) trait ValueExt { /// value type fn json_type_name(&self) -> &'static str; - /// Convert this value to an instance of `apollo_compiler::ast::Value` - fn to_ast(&self) -> apollo_compiler::ast::Value; - fn as_i32(&self) -> Option; } @@ -542,37 +539,6 @@ impl ValueExt for Value { } } - fn to_ast(&self) -> apollo_compiler::ast::Value { - match self { - Value::Null => apollo_compiler::ast::Value::Null, - Value::Bool(b) => apollo_compiler::ast::Value::Boolean(*b), - Value::Number(n) if n.is_f64() => { - apollo_compiler::ast::Value::Float(n.as_f64().expect("is float").into()) - } - Value::Number(n) => { - apollo_compiler::ast::Value::Int((n.as_i64().expect("is int") as i32).into()) - } - Value::String(s) => apollo_compiler::ast::Value::String(s.as_str().to_string()), - Value::Array(inner_vars) => apollo_compiler::ast::Value::List( - inner_vars - .iter() - .map(|v| apollo_compiler::Node::new(v.to_ast())) - .collect(), - ), - Value::Object(inner_vars) => apollo_compiler::ast::Value::Object( - inner_vars - .iter() - .map(|(k, v)| { - ( - apollo_compiler::Name::new(k.as_str()).expect("is valid name"), - apollo_compiler::Node::new(v.to_ast()), - ) - }) - .collect(), - ), - } - } - fn as_i32(&self) -> Option { self.as_i64()?.to_i32() } diff --git a/apollo-router/src/plugins/demand_control/cost_calculator/fixtures/arbitrary_json_schema.graphql b/apollo-router/src/plugins/demand_control/cost_calculator/fixtures/arbitrary_json_schema.graphql new file mode 100644 index 0000000000..2b4d7565f3 --- /dev/null +++ b/apollo-router/src/plugins/demand_control/cost_calculator/fixtures/arbitrary_json_schema.graphql @@ -0,0 +1,94 @@ +schema + @link(url: "https://specs.apollo.dev/link/v1.0") + @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) { + query: Query +} + +directive @join__directive( + graphs: [join__Graph!] + name: String! + args: join__DirectiveArguments +) repeatable on SCHEMA | OBJECT | INTERFACE | FIELD_DEFINITION + +directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE + +directive @join__field( + graph: join__Graph + requires: join__FieldSet + provides: join__FieldSet + type: String + external: Boolean + override: String + usedOverridden: Boolean + overrideLabel: String + contextArguments: [join__ContextArgument!] +) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION + +directive @join__graph(name: String!, url: String!) on ENUM_VALUE + +directive @join__implements( + graph: join__Graph! + interface: String! +) repeatable on OBJECT | INTERFACE + +directive @join__type( + graph: join__Graph! + key: join__FieldSet + extension: Boolean! = false + resolvable: Boolean! = true + isInterfaceObject: Boolean! = false +) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR + +directive @join__unionMember( + graph: join__Graph! + member: String! +) repeatable on UNION + +directive @link( + url: String + as: String + for: link__Purpose + import: [link__Import] +) repeatable on SCHEMA + +scalar ArbitraryJson @join__type(graph: SUBGRAPHWITHCUSTOMSCALAR) + +input join__ContextArgument { + name: String! + type: String! + context: String! + selection: join__FieldValue! +} + +scalar join__DirectiveArguments + +scalar join__FieldSet + +scalar join__FieldValue + +enum join__Graph { + SUBGRAPHWITHCUSTOMSCALAR + @join__graph(name: "subgraphWithCustomScalar", url: "http://localhost:4001") +} + +scalar link__Import + +enum link__Purpose { + """ + `SECURITY` features provide metadata necessary to securely resolve fields. + """ + SECURITY + + """ + `EXECUTION` features provide metadata necessary for operation execution. + """ + EXECUTION +} + +input MyInput @join__type(graph: SUBGRAPHWITHCUSTOMSCALAR) { + json: ArbitraryJson +} + +type Query @join__type(graph: SUBGRAPHWITHCUSTOMSCALAR) { + fetch(args: MyInput): String +} diff --git a/apollo-router/src/plugins/demand_control/cost_calculator/static_cost.rs b/apollo-router/src/plugins/demand_control/cost_calculator/static_cost.rs index 3c0d973ebb..397f33e9b6 100644 --- a/apollo-router/src/plugins/demand_control/cost_calculator/static_cost.rs +++ b/apollo-router/src/plugins/demand_control/cost_calculator/static_cost.rs @@ -22,7 +22,6 @@ use super::DemandControlError; use crate::graphql::Response; use crate::graphql::ResponseVisitor; use crate::json_ext::Object; -use crate::json_ext::ValueExt; use crate::plugins::demand_control::cost_calculator::directives::CostDirective; use crate::plugins::demand_control::cost_calculator::directives::ListSizeDirective; use crate::query_planner::fetch::SubgraphOperation; @@ -50,8 +49,6 @@ fn score_argument( schema: &DemandControlledSchema, variables: &Object, ) -> Result { - let cost_directive = - CostDirective::from_argument(schema.directive_name_map(), argument_definition); let ty = schema .types .get(argument_definition.ty.inner_named_type()) @@ -62,6 +59,9 @@ fn score_argument( argument_definition.ty.inner_named_type() )) })?; + let cost_directive = + CostDirective::from_argument(schema.directive_name_map(), argument_definition) + .or(CostDirective::from_type(schema.directive_name_map(), ty)); match (argument, ty) { (_, ExtendedType::Interface(_)) @@ -99,7 +99,7 @@ fn score_argument( // We make a best effort attempt to score the variable, but some of these may not exist in the variables // sent on the supergraph request, such as `$representations`. if let Some(variable) = variables.get(name.as_str()) { - score_argument(&variable.to_ast(), argument_definition, schema, variables) + score_variable(variable, argument_definition, schema) } else { Ok(0.0) } @@ -109,6 +109,62 @@ fn score_argument( } } +fn score_variable( + variable: &Value, + argument_definition: &Node, + schema: &DemandControlledSchema, +) -> Result { + let ty = schema + .types + .get(argument_definition.ty.inner_named_type()) + .ok_or_else(|| { + DemandControlError::QueryParseFailure(format!( + "Argument {} was found in query, but its type ({}) was not found in the schema", + argument_definition.name, + argument_definition.ty.inner_named_type() + )) + })?; + let cost_directive = + CostDirective::from_argument(schema.directive_name_map(), argument_definition) + .or(CostDirective::from_type(schema.directive_name_map(), ty)); + + match (variable, ty) { + (_, ExtendedType::Interface(_)) + | (_, ExtendedType::Object(_)) + | (_, ExtendedType::Union(_)) => Err(DemandControlError::QueryParseFailure( + format!( + "Argument {} has type {}, but objects, interfaces, and unions are disallowed in this position", + argument_definition.name, + argument_definition.ty.inner_named_type() + ) + )), + + (Value::Object(inner_args), ExtendedType::InputObject(inner_arg_defs)) => { + let mut cost = cost_directive.map_or(1.0, |cost| cost.weight()); + for (arg_name, arg_val) in inner_args { + let arg_def = inner_arg_defs.fields.get(arg_name.as_str()).ok_or_else(|| { + DemandControlError::QueryParseFailure(format!( + "Argument {} was found in query, but its type ({}) was not found in the schema", + argument_definition.name, + argument_definition.ty.inner_named_type() + )) + })?; + cost += score_variable(arg_val, arg_def, schema)?; + } + Ok(cost) + } + (Value::Array(inner_args), _) => { + let mut cost = cost_directive.map_or(0.0, |cost| cost.weight()); + for arg_val in inner_args { + cost += score_variable(arg_val, argument_definition, schema)?; + } + Ok(cost) + } + (Value::Null, _) => Ok(0.0), + _ => Ok(cost_directive.map_or(0.0, |cost| cost.weight())) + } +} + impl StaticCostCalculator { pub(crate) fn new( supergraph_schema: Arc, @@ -1073,4 +1129,25 @@ mod tests { assert_eq!(planned_cost_rust(schema, query, variables), 127.0); assert_eq!(actual_cost(schema, query, variables, response), 125.0); } + + #[test] + fn arbitrary_json_as_custom_scalar_in_variables() { + let schema = include_str!("./fixtures/arbitrary_json_schema.graphql"); + let query = r#" + query FetchData($myJsonValue: ArbitraryJson) { + fetch(args: { + json: $myJsonValue + }) + } + "#; + let variables = r#" + { + "myJsonValue": { + "field.with.dots": 1 + } + } + "#; + + assert_eq!(estimated_cost(schema, query, variables), 1.0); + } } diff --git a/apollo-router/src/query_planner/caching_query_planner.rs b/apollo-router/src/query_planner/caching_query_planner.rs index ee5db8dccb..209adcc856 100644 --- a/apollo-router/src/query_planner/caching_query_planner.rs +++ b/apollo-router/src/query_planner/caching_query_planner.rs @@ -56,8 +56,6 @@ pub(crate) const APOLLO_OPERATION_ID: &str = "apollo_operation_id"; #[derive(Debug, Clone, Hash)] pub(crate) enum ConfigMode { - //FIXME: add the Rust planner structure once it is hashable and serializable, - // for now use the JS config as it expected to be identical to the Rust one Rust(Arc), Both(Arc), BothBestEffort(Arc), diff --git a/apollo-router/src/query_planner/convert.rs b/apollo-router/src/query_planner/convert.rs index 27592834c6..640ecb624f 100644 --- a/apollo-router/src/query_planner/convert.rs +++ b/apollo-router/src/query_planner/convert.rs @@ -324,6 +324,7 @@ impl From<&'_ next::FetchDataPathElement> for crate::json_ext::PathElement { }) } next::FetchDataPathElement::TypenameEquals(value) => Self::Fragment(value.to_string()), + next::FetchDataPathElement::Parent => Self::Key("..".to_owned(), None), } } } diff --git a/apollo-router/src/testdata/supergraph_with_context.graphql b/apollo-router/src/testdata/supergraph_with_context.graphql index a1627ab52e..77eabbb31c 100644 --- a/apollo-router/src/testdata/supergraph_with_context.graphql +++ b/apollo-router/src/testdata/supergraph_with_context.graphql @@ -22,7 +22,7 @@ directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE directive @join__directive(graphs: [join__Graph!], name: String!, args: join__DirectiveArguments) repeatable on SCHEMA | OBJECT | INTERFACE | FIELD_DEFINITION -directive @context(name: String!) repeatable on INTERFACE | OBJECT +directive @context(name: String!) repeatable on INTERFACE | OBJECT | UNION directive @context__fromContext(field: String) on ARGUMENT_DEFINITION diff --git a/apollo-router/tests/fixtures/set_context/one_fetch_failure.json b/apollo-router/tests/fixtures/set_context/one_fetch_failure.json index 5515102f2d..311ebfc23c 100644 --- a/apollo-router/tests/fixtures/set_context/one_fetch_failure.json +++ b/apollo-router/tests/fixtures/set_context/one_fetch_failure.json @@ -41,6 +41,29 @@ } } } + }, + { + "request": { + "query": "query Query_fetch_failure__Subgraph1__2($representations:[_Any!]!$contextualArgument__Subgraph1_0:String){_entities(representations:$representations){...on U{field(a:$contextualArgument__Subgraph1_0)}}}", + "operationName": "Query_fetch_failure__Subgraph1__2", + "variables": { + "contextualArgument__Subgraph1_0": "prop value", + "representations": [{ "__typename": "U", "id": "1" }] + } + }, + "response": { + "data": { + "t": { + "__typename": "T", + "prop": "prop value", + "id": "1", + "u": { + "__typename": "U", + "id": "1" + } + } + } + } } ] } \ No newline at end of file diff --git a/apollo-router/tests/fixtures/set_context/one_null_param.json b/apollo-router/tests/fixtures/set_context/one_null_param.json index f36994a1a0..f4db338c19 100644 --- a/apollo-router/tests/fixtures/set_context/one_null_param.json +++ b/apollo-router/tests/fixtures/set_context/one_null_param.json @@ -38,6 +38,26 @@ ] } } + }, + { + "request": { + "query": "query Query_Null_Param__Subgraph1__1($representations:[_Any!]!$contextualArgument__Subgraph1_0:String){_entities(representations:$representations){...on U{field(a:$contextualArgument__Subgraph1_0)}}}", + "operationName": "Query_Null_Param__Subgraph1__1", + "variables": { + "contextualArgument__Subgraph1_0": null, + "representations": [{ "__typename": "U", "id": "1" }] + } + }, + "response": { + "data": { + "_entities": [ + { + "id": "1", + "field": 1234 + } + ] + } + } } ] } \ No newline at end of file diff --git a/apollo-router/tests/integration/query_planner.rs b/apollo-router/tests/integration/query_planner.rs index 03056ab47d..4b1c1ab70e 100644 --- a/apollo-router/tests/integration/query_planner.rs +++ b/apollo-router/tests/integration/query_planner.rs @@ -185,82 +185,8 @@ async fn context_with_new_qp() { .build() .await; router.start().await; - router - .assert_log_contains( - "could not create router: \ - failed to initialize the query planner: \ - `experimental_query_planner_mode: new` or `both` cannot yet \ - be used with `@context`. \ - Remove uses of `@context` to try the experimental query planner, \ - otherwise switch back to `legacy` or `both_best_effort`.", - ) - .await; - router.assert_shutdown().await; -} - -#[tokio::test(flavor = "multi_thread")] -async fn context_with_legacy_qp_change_to_new_qp_keeps_old_config() { - if !graph_os_enabled() { - return; - } - let config = format!("{PROMETHEUS_METRICS_CONFIG}\n{LEGACY_QP}"); - let mut router = IntegrationTest::builder() - .config(config) - .supergraph("tests/fixtures/set_context/supergraph.graphql") - .build() - .await; - router.start().await; - router.assert_started().await; - router.execute_default_query().await; - let config = format!("{PROMETHEUS_METRICS_CONFIG}\n{NEW_QP}"); - router.update_config(&config).await; - router - .assert_log_contains("error while reloading, continuing with previous configuration") - .await; - router - .assert_metrics_contains( - r#"apollo_router_lifecycle_query_planner_init_total{init_error_kind="context",init_is_success="false",otel_scope_name="apollo/router"} 1"#, - None, - ) - .await; - router.execute_default_query().await; - router.graceful_shutdown().await; -} - -#[tokio::test(flavor = "multi_thread")] -async fn context_with_legacy_qp_reload_to_both_best_effort_keep_previous_config() { - if !graph_os_enabled() { - return; - } - let config = format!("{PROMETHEUS_METRICS_CONFIG}\n{LEGACY_QP}"); - let mut router = IntegrationTest::builder() - .config(config) - .supergraph("tests/fixtures/set_context/supergraph.graphql") - .build() - .await; - router.start().await; router.assert_started().await; router.execute_default_query().await; - - let config = format!("{PROMETHEUS_METRICS_CONFIG}\n{BOTH_BEST_EFFORT_QP}"); - router.update_config(&config).await; - router - .assert_log_contains( - "Falling back to the legacy query planner: \ - failed to initialize the query planner: \ - `experimental_query_planner_mode: new` or `both` cannot yet \ - be used with `@context`. \ - Remove uses of `@context` to try the experimental query planner, \ - otherwise switch back to `legacy` or `both_best_effort`.", - ) - .await; - router - .assert_metrics_contains( - r#"apollo_router_lifecycle_query_planner_init_total{init_error_kind="context",init_is_success="false",otel_scope_name="apollo/router"} 1"#, - None, - ) - .await; - router.execute_default_query().await; router.graceful_shutdown().await; } diff --git a/apollo-router/tests/set_context.rs b/apollo-router/tests/set_context.rs index aae8107137..dc3f366fcf 100644 --- a/apollo-router/tests/set_context.rs +++ b/apollo-router/tests/set_context.rs @@ -32,9 +32,10 @@ macro_rules! snap } } -async fn run_single_request(query: &str, mocks: &[(&'static str, &'static str)]) -> Response { - let harness = setup_from_mocks( - json! {{ +fn get_configuration(rust_qp: bool) -> serde_json::Value { + if rust_qp { + return json! {{ + "experimental_query_planner_mode": "new", "experimental_type_conditioned_fetching": true, // will make debugging easier "plugins": { @@ -47,9 +48,31 @@ async fn run_single_request(query: &str, mocks: &[(&'static str, &'static str)]) // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 "generate_query_fragments": false, } - }}, - mocks, - ); + }}; + } + json! {{ + "experimental_type_conditioned_fetching": true, + // will make debugging easier + "plugins": { + "experimental.expose_query_plan": true + }, + "include_subgraph_errors": { + "all": true + }, + "supergraph": { + // TODO(@goto-bus-stop): need to update the mocks and remove this, #6013 + "generate_query_fragments": false, + } + }} +} + +async fn run_single_request( + query: &str, + rust_qp: bool, + mocks: &[(&'static str, &'static str)], +) -> Response { + let configuration = get_configuration(rust_qp); + let harness = setup_from_mocks(configuration, mocks); let supergraph_service = harness.build_supergraph().await.unwrap(); let request = supergraph::Request::fake_builder() .query(query.to_string()) @@ -83,6 +106,34 @@ async fn test_set_context() { let response = run_single_request( QUERY, + false, + &[ + ("Subgraph1", include_str!("fixtures/set_context/one.json")), + ("Subgraph2", include_str!("fixtures/set_context/two.json")), + ], + ) + .await; + + snap!(response); +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_set_context_rust_qp() { + static QUERY: &str = r#" + query set_context_rust_qp { + t { + __typename + id + u { + __typename + field + } + } + }"#; + + let response = run_single_request( + QUERY, + true, &[ ("Subgraph1", include_str!("fixtures/set_context/one.json")), ("Subgraph2", include_str!("fixtures/set_context/two.json")), @@ -107,6 +158,32 @@ async fn test_set_context_no_typenames() { let response = run_single_request( QUERY_NO_TYPENAMES, + false, + &[ + ("Subgraph1", include_str!("fixtures/set_context/one.json")), + ("Subgraph2", include_str!("fixtures/set_context/two.json")), + ], + ) + .await; + + snap!(response); +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_set_context_no_typenames_rust_qp() { + static QUERY_NO_TYPENAMES: &str = r#" + query set_context_no_typenames_rust_qp { + t { + id + u { + field + } + } + }"#; + + let response = run_single_request( + QUERY_NO_TYPENAMES, + true, &[ ("Subgraph1", include_str!("fixtures/set_context/one.json")), ("Subgraph2", include_str!("fixtures/set_context/two.json")), @@ -131,6 +208,32 @@ async fn test_set_context_list() { let response = run_single_request( QUERY_WITH_LIST, + false, + &[ + ("Subgraph1", include_str!("fixtures/set_context/one.json")), + ("Subgraph2", include_str!("fixtures/set_context/two.json")), + ], + ) + .await; + + snap!(response); +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_set_context_list_rust_qp() { + static QUERY_WITH_LIST: &str = r#" + query set_context_list_rust_qp { + t { + id + uList { + field + } + } + }"#; + + let response = run_single_request( + QUERY_WITH_LIST, + true, &[ ("Subgraph1", include_str!("fixtures/set_context/one.json")), ("Subgraph2", include_str!("fixtures/set_context/two.json")), @@ -155,6 +258,32 @@ async fn test_set_context_list_of_lists() { let response = run_single_request( QUERY_WITH_LIST_OF_LISTS, + false, + &[ + ("Subgraph1", include_str!("fixtures/set_context/one.json")), + ("Subgraph2", include_str!("fixtures/set_context/two.json")), + ], + ) + .await; + + snap!(response); +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_set_context_list_of_lists_rust_qp() { + static QUERY_WITH_LIST_OF_LISTS: &str = r#" + query QueryLL { + tList { + id + uList { + field + } + } + }"#; + + let response = run_single_request( + QUERY_WITH_LIST_OF_LISTS, + true, &[ ("Subgraph1", include_str!("fixtures/set_context/one.json")), ("Subgraph2", include_str!("fixtures/set_context/two.json")), @@ -185,6 +314,38 @@ async fn test_set_context_union() { let response = run_single_request( QUERY_WITH_UNION, + false, + &[ + ("Subgraph1", include_str!("fixtures/set_context/one.json")), + ("Subgraph2", include_str!("fixtures/set_context/two.json")), + ], + ) + .await; + + snap!(response); +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_set_context_union_rust_qp() { + static QUERY_WITH_UNION: &str = r#" + query QueryUnion { + k { + ... on A { + v { + field + } + } + ... on B { + v { + field + } + } + } + }"#; + + let response = run_single_request( + QUERY_WITH_UNION, + true, &[ ("Subgraph1", include_str!("fixtures/set_context/one.json")), ("Subgraph2", include_str!("fixtures/set_context/two.json")), @@ -209,6 +370,35 @@ async fn test_set_context_with_null() { let response = run_single_request( QUERY, + false, + &[ + ( + "Subgraph1", + include_str!("fixtures/set_context/one_null_param.json"), + ), + ("Subgraph2", include_str!("fixtures/set_context/two.json")), + ], + ) + .await; + + insta::assert_json_snapshot!(response); +} + +#[tokio::test(flavor = "multi_thread")] +async fn test_set_context_with_null_rust_qp() { + static QUERY: &str = r#" + query Query_Null_Param { + t { + id + u { + field + } + } + }"#; + + let response = run_single_request( + QUERY, + true, &[ ( "Subgraph1", @@ -238,6 +428,34 @@ async fn test_set_context_type_mismatch() { let response = run_single_request( QUERY, + false, + &[ + ("Subgraph1", include_str!("fixtures/set_context/one.json")), + ("Subgraph2", include_str!("fixtures/set_context/two.json")), + ], + ) + .await; + + snap!(response); +} + +// this test returns the contextual value with a different than expected type +// this currently works, but perhaps should do type valdiation in the future to reject +#[tokio::test(flavor = "multi_thread")] +async fn test_set_context_type_mismatch_rust_qp() { + static QUERY: &str = r#" + query Query_type_mismatch { + t { + id + u { + field + } + } + }"#; + + let response = run_single_request( + QUERY, + true, &[ ("Subgraph1", include_str!("fixtures/set_context/one.json")), ("Subgraph2", include_str!("fixtures/set_context/two.json")), @@ -265,6 +483,38 @@ async fn test_set_context_unrelated_fetch_failure() { let response = run_single_request( QUERY, + false, + &[ + ( + "Subgraph1", + include_str!("fixtures/set_context/one_fetch_failure.json"), + ), + ("Subgraph2", include_str!("fixtures/set_context/two.json")), + ], + ) + .await; + + snap!(response); +} + +// fetch from unrelated (to context) subgraph fails +// validates that the error propagation is correct +#[tokio::test(flavor = "multi_thread")] +async fn test_set_context_unrelated_fetch_failure_rust_qp() { + static QUERY: &str = r#" + query Query_fetch_failure { + t { + id + u { + field + b + } + } + }"#; + + let response = run_single_request( + QUERY, + true, &[ ( "Subgraph1", @@ -294,6 +544,37 @@ async fn test_set_context_dependent_fetch_failure() { let response = run_single_request( QUERY, + false, + &[ + ( + "Subgraph1", + include_str!("fixtures/set_context/one_dependent_fetch_failure.json"), + ), + ("Subgraph2", include_str!("fixtures/set_context/two.json")), + ], + ) + .await; + + snap!(response); +} + +// subgraph fetch fails where context depends on results of fetch. +// validates that no fetch will get called that passes context +#[tokio::test(flavor = "multi_thread")] +async fn test_set_context_dependent_fetch_failure_rust_qp() { + static QUERY: &str = r#" + query Query_fetch_dependent_failure { + t { + id + u { + field + } + } + }"#; + + let response = run_single_request( + QUERY, + true, &[ ( "Subgraph1", diff --git a/apollo-router/tests/snapshots/set_context__set_context_dependent_fetch_failure_rust_qp.snap b/apollo-router/tests/snapshots/set_context__set_context_dependent_fetch_failure_rust_qp.snap new file mode 100644 index 0000000000..5caea23420 --- /dev/null +++ b/apollo-router/tests/snapshots/set_context__set_context_dependent_fetch_failure_rust_qp.snap @@ -0,0 +1,115 @@ +--- +source: apollo-router/tests/set_context.rs +expression: response +--- +{ + "data": null, + "errors": [ + { + "message": "Some error", + "locations": [ + { + "line": 3, + "column": 5 + } + ], + "path": [ + "t", + "u" + ], + "extensions": { + "service": "Subgraph1" + } + } + ], + "extensions": { + "apolloQueryPlan": { + "object": { + "kind": "QueryPlan", + "node": { + "kind": "Sequence", + "nodes": [ + { + "authorization": { + "is_authenticated": false, + "policies": [], + "scopes": [] + }, + "contextRewrites": null, + "id": null, + "inputRewrites": null, + "kind": "Fetch", + "operation": "query Query_fetch_dependent_failure__Subgraph1__0 { t { __typename prop id u { __typename id } } }", + "operationKind": "query", + "operationName": "Query_fetch_dependent_failure__Subgraph1__0", + "outputRewrites": null, + "schemaAwareHash": "6b659295c8e5aff7b3d7146b878e848b43ad58fba3f4dfce2988530631c3448a", + "serviceName": "Subgraph1", + "variableUsages": [] + }, + { + "kind": "Flatten", + "node": { + "authorization": { + "is_authenticated": false, + "policies": [], + "scopes": [] + }, + "contextRewrites": [ + { + "kind": "KeyRenamer", + "path": [ + "..", + "... on T", + "prop" + ], + "renameKeyTo": "contextualArgument_1_0" + } + ], + "id": null, + "inputRewrites": null, + "kind": "Fetch", + "operation": "query Query_fetch_dependent_failure__Subgraph1__1($representations: [_Any!]!, $contextualArgument_1_0: String) { _entities(representations: $representations) { ... on U { field(a: $contextualArgument_1_0) } } }", + "operationKind": "query", + "operationName": "Query_fetch_dependent_failure__Subgraph1__1", + "outputRewrites": null, + "requires": [ + { + "kind": "InlineFragment", + "selections": [ + { + "kind": "Field", + "name": "__typename" + }, + { + "kind": "Field", + "name": "id" + } + ], + "typeCondition": "U" + } + ], + "schemaAwareHash": "3bc84712c95d01c4e9118cc1f8179e071662862a04cef56d39a0ac6a621daf36", + "serviceName": "Subgraph1", + "variableUsages": [ + "contextualArgument_1_0" + ] + }, + "path": [ + "t", + "u" + ] + } + ] + } + }, + "text": "QueryPlan {\n Sequence {\n Fetch(service: \"Subgraph1\") {\n {\n t {\n __typename\n prop\n id\n u {\n __typename\n id\n }\n }\n }\n },\n Flatten(path: \"t.u\") {\n Fetch(service: \"Subgraph1\") {\n {\n ... on U {\n __typename\n id\n }\n } =>\n {\n ... on U {\n field(a: $contextualArgument_1_0)\n }\n }\n },\n },\n },\n}" + }, + "valueCompletion": [ + { + "message": "Cannot return null for non-nullable field Query.t", + "path": [] + } + ] + } +} diff --git a/apollo-router/tests/snapshots/set_context__set_context_list_of_lists_rust_qp.snap b/apollo-router/tests/snapshots/set_context__set_context_list_of_lists_rust_qp.snap new file mode 100644 index 0000000000..0945ccf058 --- /dev/null +++ b/apollo-router/tests/snapshots/set_context__set_context_list_of_lists_rust_qp.snap @@ -0,0 +1,112 @@ +--- +source: apollo-router/tests/set_context.rs +expression: response +--- +{ + "data": { + "tList": [ + { + "id": "1", + "uList": [ + { + "field": 3456 + } + ] + }, + { + "id": "2", + "uList": [ + { + "field": 4567 + } + ] + } + ] + }, + "extensions": { + "apolloQueryPlan": { + "object": { + "kind": "QueryPlan", + "node": { + "kind": "Sequence", + "nodes": [ + { + "authorization": { + "is_authenticated": false, + "policies": [], + "scopes": [] + }, + "contextRewrites": null, + "id": null, + "inputRewrites": null, + "kind": "Fetch", + "operation": "query QueryLL__Subgraph1__0 { tList { __typename prop id uList { __typename id } } }", + "operationKind": "query", + "operationName": "QueryLL__Subgraph1__0", + "outputRewrites": null, + "schemaAwareHash": "0a6255094b34a44c5addf88a5a9bb37847f19ecf10370be675ba55a1330b4ac7", + "serviceName": "Subgraph1", + "variableUsages": [] + }, + { + "kind": "Flatten", + "node": { + "authorization": { + "is_authenticated": false, + "policies": [], + "scopes": [] + }, + "contextRewrites": [ + { + "kind": "KeyRenamer", + "path": [ + "..", + "... on T", + "prop" + ], + "renameKeyTo": "contextualArgument_1_0" + } + ], + "id": null, + "inputRewrites": null, + "kind": "Fetch", + "operation": "query QueryLL__Subgraph1__1($representations: [_Any!]!, $contextualArgument_1_0: String) { _entities(representations: $representations) { ... on U { field(a: $contextualArgument_1_0) } } }", + "operationKind": "query", + "operationName": "QueryLL__Subgraph1__1", + "outputRewrites": null, + "requires": [ + { + "kind": "InlineFragment", + "selections": [ + { + "kind": "Field", + "name": "__typename" + }, + { + "kind": "Field", + "name": "id" + } + ], + "typeCondition": "U" + } + ], + "schemaAwareHash": "71e6d73b679197d0e979c07446c670bad69897d77bd280dc9c39276fde6e8d99", + "serviceName": "Subgraph1", + "variableUsages": [ + "contextualArgument_1_0" + ] + }, + "path": [ + "tList", + "@", + "uList", + "@" + ] + } + ] + } + }, + "text": "QueryPlan {\n Sequence {\n Fetch(service: \"Subgraph1\") {\n {\n tList {\n __typename\n prop\n id\n uList {\n __typename\n id\n }\n }\n }\n },\n Flatten(path: \"tList.@.uList.@\") {\n Fetch(service: \"Subgraph1\") {\n {\n ... on U {\n __typename\n id\n }\n } =>\n {\n ... on U {\n field(a: $contextualArgument_1_0)\n }\n }\n },\n },\n },\n}" + } + } +} diff --git a/apollo-router/tests/snapshots/set_context__set_context_list_rust_qp.snap b/apollo-router/tests/snapshots/set_context__set_context_list_rust_qp.snap new file mode 100644 index 0000000000..ab643923c0 --- /dev/null +++ b/apollo-router/tests/snapshots/set_context__set_context_list_rust_qp.snap @@ -0,0 +1,107 @@ +--- +source: apollo-router/tests/set_context.rs +expression: response +--- +{ + "data": { + "t": { + "id": "1", + "uList": [ + { + "field": 1234 + }, + { + "field": 2345 + }, + { + "field": 3456 + } + ] + } + }, + "extensions": { + "apolloQueryPlan": { + "object": { + "kind": "QueryPlan", + "node": { + "kind": "Sequence", + "nodes": [ + { + "authorization": { + "is_authenticated": false, + "policies": [], + "scopes": [] + }, + "contextRewrites": null, + "id": null, + "inputRewrites": null, + "kind": "Fetch", + "operation": "query set_context_list_rust_qp__Subgraph1__0 { t { __typename prop id uList { __typename id } } }", + "operationKind": "query", + "operationName": "set_context_list_rust_qp__Subgraph1__0", + "outputRewrites": null, + "schemaAwareHash": "fd215e24828b3a7296abe901f843f68b525d8eaf35a019ac34a2198738c91230", + "serviceName": "Subgraph1", + "variableUsages": [] + }, + { + "kind": "Flatten", + "node": { + "authorization": { + "is_authenticated": false, + "policies": [], + "scopes": [] + }, + "contextRewrites": [ + { + "kind": "KeyRenamer", + "path": [ + "..", + "... on T", + "prop" + ], + "renameKeyTo": "contextualArgument_1_0" + } + ], + "id": null, + "inputRewrites": null, + "kind": "Fetch", + "operation": "query set_context_list_rust_qp__Subgraph1__1($representations: [_Any!]!, $contextualArgument_1_0: String) { _entities(representations: $representations) { ... on U { field(a: $contextualArgument_1_0) } } }", + "operationKind": "query", + "operationName": "set_context_list_rust_qp__Subgraph1__1", + "outputRewrites": null, + "requires": [ + { + "kind": "InlineFragment", + "selections": [ + { + "kind": "Field", + "name": "__typename" + }, + { + "kind": "Field", + "name": "id" + } + ], + "typeCondition": "U" + } + ], + "schemaAwareHash": "96a8bf16a86cbddab93bb46364f8b0e63635a928924dcb681dc2371b810eee02", + "serviceName": "Subgraph1", + "variableUsages": [ + "contextualArgument_1_0" + ] + }, + "path": [ + "t", + "uList", + "@" + ] + } + ] + } + }, + "text": "QueryPlan {\n Sequence {\n Fetch(service: \"Subgraph1\") {\n {\n t {\n __typename\n prop\n id\n uList {\n __typename\n id\n }\n }\n }\n },\n Flatten(path: \"t.uList.@\") {\n Fetch(service: \"Subgraph1\") {\n {\n ... on U {\n __typename\n id\n }\n } =>\n {\n ... on U {\n field(a: $contextualArgument_1_0)\n }\n }\n },\n },\n },\n}" + } + } +} diff --git a/apollo-router/tests/snapshots/set_context__set_context_no_typenames_rust_qp.snap b/apollo-router/tests/snapshots/set_context__set_context_no_typenames_rust_qp.snap new file mode 100644 index 0000000000..6a47496428 --- /dev/null +++ b/apollo-router/tests/snapshots/set_context__set_context_no_typenames_rust_qp.snap @@ -0,0 +1,98 @@ +--- +source: apollo-router/tests/set_context.rs +expression: response +--- +{ + "data": { + "t": { + "id": "1", + "u": { + "field": 1234 + } + } + }, + "extensions": { + "apolloQueryPlan": { + "object": { + "kind": "QueryPlan", + "node": { + "kind": "Sequence", + "nodes": [ + { + "authorization": { + "is_authenticated": false, + "policies": [], + "scopes": [] + }, + "contextRewrites": null, + "id": null, + "inputRewrites": null, + "kind": "Fetch", + "operation": "query set_context_no_typenames_rust_qp__Subgraph1__0 { t { __typename prop id u { __typename id } } }", + "operationKind": "query", + "operationName": "set_context_no_typenames_rust_qp__Subgraph1__0", + "outputRewrites": null, + "schemaAwareHash": "9c1d7c67821fc43d63e8a217417fbe600a9100e1a43ba50e2f961d4fd4974144", + "serviceName": "Subgraph1", + "variableUsages": [] + }, + { + "kind": "Flatten", + "node": { + "authorization": { + "is_authenticated": false, + "policies": [], + "scopes": [] + }, + "contextRewrites": [ + { + "kind": "KeyRenamer", + "path": [ + "..", + "... on T", + "prop" + ], + "renameKeyTo": "contextualArgument_1_0" + } + ], + "id": null, + "inputRewrites": null, + "kind": "Fetch", + "operation": "query set_context_no_typenames_rust_qp__Subgraph1__1($representations: [_Any!]!, $contextualArgument_1_0: String) { _entities(representations: $representations) { ... on U { field(a: $contextualArgument_1_0) } } }", + "operationKind": "query", + "operationName": "set_context_no_typenames_rust_qp__Subgraph1__1", + "outputRewrites": null, + "requires": [ + { + "kind": "InlineFragment", + "selections": [ + { + "kind": "Field", + "name": "__typename" + }, + { + "kind": "Field", + "name": "id" + } + ], + "typeCondition": "U" + } + ], + "schemaAwareHash": "5fdc56a38428bad98d0c5e46f096c0179886815509ffc1918f5c6e0a784e2547", + "serviceName": "Subgraph1", + "variableUsages": [ + "contextualArgument_1_0" + ] + }, + "path": [ + "t", + "u" + ] + } + ] + } + }, + "text": "QueryPlan {\n Sequence {\n Fetch(service: \"Subgraph1\") {\n {\n t {\n __typename\n prop\n id\n u {\n __typename\n id\n }\n }\n }\n },\n Flatten(path: \"t.u\") {\n Fetch(service: \"Subgraph1\") {\n {\n ... on U {\n __typename\n id\n }\n } =>\n {\n ... on U {\n field(a: $contextualArgument_1_0)\n }\n }\n },\n },\n },\n}" + } + } +} diff --git a/apollo-router/tests/snapshots/set_context__set_context_rust_qp.snap b/apollo-router/tests/snapshots/set_context__set_context_rust_qp.snap new file mode 100644 index 0000000000..fecc966894 --- /dev/null +++ b/apollo-router/tests/snapshots/set_context__set_context_rust_qp.snap @@ -0,0 +1,100 @@ +--- +source: apollo-router/tests/set_context.rs +expression: response +--- +{ + "data": { + "t": { + "__typename": "T", + "id": "1", + "u": { + "__typename": "U", + "field": 1234 + } + } + }, + "extensions": { + "apolloQueryPlan": { + "object": { + "kind": "QueryPlan", + "node": { + "kind": "Sequence", + "nodes": [ + { + "authorization": { + "is_authenticated": false, + "policies": [], + "scopes": [] + }, + "contextRewrites": null, + "id": null, + "inputRewrites": null, + "kind": "Fetch", + "operation": "query set_context_rust_qp__Subgraph1__0 { t { __typename prop id u { __typename id } } }", + "operationKind": "query", + "operationName": "set_context_rust_qp__Subgraph1__0", + "outputRewrites": null, + "schemaAwareHash": "7fb5b477b89d2dcf76239dd30abcf6210462e144376a6b1b589ceb603edd55cd", + "serviceName": "Subgraph1", + "variableUsages": [] + }, + { + "kind": "Flatten", + "node": { + "authorization": { + "is_authenticated": false, + "policies": [], + "scopes": [] + }, + "contextRewrites": [ + { + "kind": "KeyRenamer", + "path": [ + "..", + "... on T", + "prop" + ], + "renameKeyTo": "contextualArgument_1_0" + } + ], + "id": null, + "inputRewrites": null, + "kind": "Fetch", + "operation": "query set_context_rust_qp__Subgraph1__1($representations: [_Any!]!, $contextualArgument_1_0: String) { _entities(representations: $representations) { ... on U { field(a: $contextualArgument_1_0) } } }", + "operationKind": "query", + "operationName": "set_context_rust_qp__Subgraph1__1", + "outputRewrites": null, + "requires": [ + { + "kind": "InlineFragment", + "selections": [ + { + "kind": "Field", + "name": "__typename" + }, + { + "kind": "Field", + "name": "id" + } + ], + "typeCondition": "U" + } + ], + "schemaAwareHash": "fef499e9ca815057242c5a03e9f0960d5c50d6958b0ac7329fc23b5a6e714eab", + "serviceName": "Subgraph1", + "variableUsages": [ + "contextualArgument_1_0" + ] + }, + "path": [ + "t", + "u" + ] + } + ] + } + }, + "text": "QueryPlan {\n Sequence {\n Fetch(service: \"Subgraph1\") {\n {\n t {\n __typename\n prop\n id\n u {\n __typename\n id\n }\n }\n }\n },\n Flatten(path: \"t.u\") {\n Fetch(service: \"Subgraph1\") {\n {\n ... on U {\n __typename\n id\n }\n } =>\n {\n ... on U {\n field(a: $contextualArgument_1_0)\n }\n }\n },\n },\n },\n}" + } + } +} diff --git a/apollo-router/tests/snapshots/set_context__set_context_type_mismatch_rust_qp.snap b/apollo-router/tests/snapshots/set_context__set_context_type_mismatch_rust_qp.snap new file mode 100644 index 0000000000..516c42f5fe --- /dev/null +++ b/apollo-router/tests/snapshots/set_context__set_context_type_mismatch_rust_qp.snap @@ -0,0 +1,98 @@ +--- +source: apollo-router/tests/set_context.rs +expression: response +--- +{ + "data": { + "t": { + "id": "1", + "u": { + "field": 1234 + } + } + }, + "extensions": { + "apolloQueryPlan": { + "object": { + "kind": "QueryPlan", + "node": { + "kind": "Sequence", + "nodes": [ + { + "authorization": { + "is_authenticated": false, + "policies": [], + "scopes": [] + }, + "contextRewrites": null, + "id": null, + "inputRewrites": null, + "kind": "Fetch", + "operation": "query Query_type_mismatch__Subgraph1__0 { t { __typename prop id u { __typename id } } }", + "operationKind": "query", + "operationName": "Query_type_mismatch__Subgraph1__0", + "outputRewrites": null, + "schemaAwareHash": "29f5e6a254fac05382ddc3e4aac47368dc9847abe711ecf17dbfca7945097faf", + "serviceName": "Subgraph1", + "variableUsages": [] + }, + { + "kind": "Flatten", + "node": { + "authorization": { + "is_authenticated": false, + "policies": [], + "scopes": [] + }, + "contextRewrites": [ + { + "kind": "KeyRenamer", + "path": [ + "..", + "... on T", + "prop" + ], + "renameKeyTo": "contextualArgument_1_0" + } + ], + "id": null, + "inputRewrites": null, + "kind": "Fetch", + "operation": "query Query_type_mismatch__Subgraph1__1($representations: [_Any!]!, $contextualArgument_1_0: String) { _entities(representations: $representations) { ... on U { field(a: $contextualArgument_1_0) } } }", + "operationKind": "query", + "operationName": "Query_type_mismatch__Subgraph1__1", + "outputRewrites": null, + "requires": [ + { + "kind": "InlineFragment", + "selections": [ + { + "kind": "Field", + "name": "__typename" + }, + { + "kind": "Field", + "name": "id" + } + ], + "typeCondition": "U" + } + ], + "schemaAwareHash": "864f2eecd06e2c450e48f2cb551d4e95946575eb7e537a17a04c9a1716c0a482", + "serviceName": "Subgraph1", + "variableUsages": [ + "contextualArgument_1_0" + ] + }, + "path": [ + "t", + "u" + ] + } + ] + } + }, + "text": "QueryPlan {\n Sequence {\n Fetch(service: \"Subgraph1\") {\n {\n t {\n __typename\n prop\n id\n u {\n __typename\n id\n }\n }\n }\n },\n Flatten(path: \"t.u\") {\n Fetch(service: \"Subgraph1\") {\n {\n ... on U {\n __typename\n id\n }\n } =>\n {\n ... on U {\n field(a: $contextualArgument_1_0)\n }\n }\n },\n },\n },\n}" + } + } +} diff --git a/apollo-router/tests/snapshots/set_context__set_context_union_rust_qp.snap b/apollo-router/tests/snapshots/set_context__set_context_union_rust_qp.snap new file mode 100644 index 0000000000..74e41f53c9 --- /dev/null +++ b/apollo-router/tests/snapshots/set_context__set_context_union_rust_qp.snap @@ -0,0 +1,173 @@ +--- +source: apollo-router/tests/set_context.rs +expression: response +--- +{ + "data": { + "k": { + "v": { + "field": 3456 + } + } + }, + "extensions": { + "apolloQueryPlan": { + "object": { + "kind": "QueryPlan", + "node": { + "kind": "Sequence", + "nodes": [ + { + "authorization": { + "is_authenticated": false, + "policies": [], + "scopes": [] + }, + "contextRewrites": null, + "id": null, + "inputRewrites": null, + "kind": "Fetch", + "operation": "query QueryUnion__Subgraph1__0 { k { __typename ... on A { __typename prop v { __typename id } } ... on B { __typename prop v { __typename id } } } }", + "operationKind": "query", + "operationName": "QueryUnion__Subgraph1__0", + "outputRewrites": null, + "schemaAwareHash": "eae4d791b0314c4e2509735ad3d0dd0ca5de8ee4c7f315513931df6e4cb5102d", + "serviceName": "Subgraph1", + "variableUsages": [] + }, + { + "kind": "Parallel", + "nodes": [ + { + "kind": "Flatten", + "node": { + "authorization": { + "is_authenticated": false, + "policies": [], + "scopes": [] + }, + "contextRewrites": [ + { + "kind": "KeyRenamer", + "path": [ + "..", + "... on A", + "prop" + ], + "renameKeyTo": "contextualArgument_1_1" + }, + { + "kind": "KeyRenamer", + "path": [ + "..", + "... on B", + "prop" + ], + "renameKeyTo": "contextualArgument_1_1" + } + ], + "id": null, + "inputRewrites": null, + "kind": "Fetch", + "operation": "query QueryUnion__Subgraph1__1($representations: [_Any!]!, $contextualArgument_1_1: String) { _entities(representations: $representations) { ... on V { field(a: $contextualArgument_1_1) } } }", + "operationKind": "query", + "operationName": "QueryUnion__Subgraph1__1", + "outputRewrites": null, + "requires": [ + { + "kind": "InlineFragment", + "selections": [ + { + "kind": "Field", + "name": "__typename" + }, + { + "kind": "Field", + "name": "id" + } + ], + "typeCondition": "V" + } + ], + "schemaAwareHash": "b1ba6dd8a0e2edc415efd084401bfa01ecbaaa76a0f7896c27c431bed8c20a08", + "serviceName": "Subgraph1", + "variableUsages": [ + "contextualArgument_1_1" + ] + }, + "path": [ + "k|[B]", + "v" + ] + }, + { + "kind": "Flatten", + "node": { + "authorization": { + "is_authenticated": false, + "policies": [], + "scopes": [] + }, + "contextRewrites": [ + { + "kind": "KeyRenamer", + "path": [ + "..", + "... on A", + "prop" + ], + "renameKeyTo": "contextualArgument_1_1" + }, + { + "kind": "KeyRenamer", + "path": [ + "..", + "... on B", + "prop" + ], + "renameKeyTo": "contextualArgument_1_1" + } + ], + "id": null, + "inputRewrites": null, + "kind": "Fetch", + "operation": "query QueryUnion__Subgraph1__2($representations: [_Any!]!, $contextualArgument_1_1: String) { _entities(representations: $representations) { ... on V { field(a: $contextualArgument_1_1) } } }", + "operationKind": "query", + "operationName": "QueryUnion__Subgraph1__2", + "outputRewrites": null, + "requires": [ + { + "kind": "InlineFragment", + "selections": [ + { + "kind": "Field", + "name": "__typename" + }, + { + "kind": "Field", + "name": "id" + } + ], + "typeCondition": "V" + } + ], + "schemaAwareHash": "45785998d1610758abe68519f9bc100828afa2ba56c7e55b9d18ad69f3ad27eb", + "serviceName": "Subgraph1", + "variableUsages": [ + "contextualArgument_1_1" + ] + }, + "path": [ + "k|[A]", + "v" + ] + } + ] + } + ] + } + }, + "text": "QueryPlan {\n Sequence {\n Fetch(service: \"Subgraph1\") {\n {\n k {\n __typename\n ... on A {\n __typename\n prop\n v {\n __typename\n id\n }\n }\n ... on B {\n __typename\n prop\n v {\n __typename\n id\n }\n }\n }\n }\n },\n Parallel {\n Flatten(path: \"k|[B].v\") {\n Fetch(service: \"Subgraph1\") {\n {\n ... on V {\n __typename\n id\n }\n } =>\n {\n ... on V {\n field(a: $contextualArgument_1_1)\n }\n }\n },\n },\n Flatten(path: \"k|[A].v\") {\n Fetch(service: \"Subgraph1\") {\n {\n ... on V {\n __typename\n id\n }\n } =>\n {\n ... on V {\n field(a: $contextualArgument_1_1)\n }\n }\n },\n },\n },\n },\n}" + } + } +} diff --git a/apollo-router/tests/snapshots/set_context__set_context_unrelated_fetch_failure_rust_qp.snap b/apollo-router/tests/snapshots/set_context__set_context_unrelated_fetch_failure_rust_qp.snap new file mode 100644 index 0000000000..b8650bb7bb --- /dev/null +++ b/apollo-router/tests/snapshots/set_context__set_context_unrelated_fetch_failure_rust_qp.snap @@ -0,0 +1,171 @@ +--- +source: apollo-router/tests/set_context.rs +expression: response +--- +{ + "data": null, + "errors": [ + { + "message": "Some error", + "path": [ + "t", + "u" + ], + "extensions": { + "service": "Subgraph2" + } + } + ], + "extensions": { + "apolloQueryPlan": { + "object": { + "kind": "QueryPlan", + "node": { + "kind": "Sequence", + "nodes": [ + { + "authorization": { + "is_authenticated": false, + "policies": [], + "scopes": [] + }, + "contextRewrites": null, + "id": null, + "inputRewrites": null, + "kind": "Fetch", + "operation": "query Query_fetch_failure__Subgraph1__0 { t { __typename prop id u { __typename id } } }", + "operationKind": "query", + "operationName": "Query_fetch_failure__Subgraph1__0", + "outputRewrites": null, + "schemaAwareHash": "d3f1ad875170d008059583ca6074e732a178f74474ac31de3bb4397c5080020d", + "serviceName": "Subgraph1", + "variableUsages": [] + }, + { + "kind": "Parallel", + "nodes": [ + { + "kind": "Flatten", + "node": { + "authorization": { + "is_authenticated": false, + "policies": [], + "scopes": [] + }, + "contextRewrites": [ + { + "kind": "KeyRenamer", + "path": [ + "..", + "... on T", + "prop" + ], + "renameKeyTo": "contextualArgument_1_0" + } + ], + "id": null, + "inputRewrites": null, + "kind": "Fetch", + "operation": "query Query_fetch_failure__Subgraph1__1($representations: [_Any!]!, $contextualArgument_1_0: String) { _entities(representations: $representations) { ... on U { field(a: $contextualArgument_1_0) } } }", + "operationKind": "query", + "operationName": "Query_fetch_failure__Subgraph1__1", + "outputRewrites": null, + "requires": [ + { + "kind": "InlineFragment", + "selections": [ + { + "kind": "Field", + "name": "__typename" + }, + { + "kind": "Field", + "name": "id" + } + ], + "typeCondition": "U" + } + ], + "schemaAwareHash": "05dc59a826cec26ad8263101508c298dd8d31d79d36f18194dd4cf8cd5f02dc3", + "serviceName": "Subgraph1", + "variableUsages": [ + "contextualArgument_1_0" + ] + }, + "path": [ + "t", + "u" + ] + }, + { + "kind": "Flatten", + "node": { + "authorization": { + "is_authenticated": false, + "policies": [], + "scopes": [] + }, + "contextRewrites": null, + "id": null, + "inputRewrites": null, + "kind": "Fetch", + "operation": "query Query_fetch_failure__Subgraph2__2($representations: [_Any!]!) { _entities(representations: $representations) { ... on U { b } } }", + "operationKind": "query", + "operationName": "Query_fetch_failure__Subgraph2__2", + "outputRewrites": null, + "requires": [ + { + "kind": "InlineFragment", + "selections": [ + { + "kind": "Field", + "name": "__typename" + }, + { + "kind": "Field", + "name": "id" + } + ], + "typeCondition": "U" + } + ], + "schemaAwareHash": "a3c7e6df6f9c93b228f16a937b7159ccf1294fec50a92f60ba004dbebbb64b50", + "serviceName": "Subgraph2", + "variableUsages": [] + }, + "path": [ + "t", + "u" + ] + } + ] + } + ] + } + }, + "text": "QueryPlan {\n Sequence {\n Fetch(service: \"Subgraph1\") {\n {\n t {\n __typename\n prop\n id\n u {\n __typename\n id\n }\n }\n }\n },\n Parallel {\n Flatten(path: \"t.u\") {\n Fetch(service: \"Subgraph1\") {\n {\n ... on U {\n __typename\n id\n }\n } =>\n {\n ... on U {\n field(a: $contextualArgument_1_0)\n }\n }\n },\n },\n Flatten(path: \"t.u\") {\n Fetch(service: \"Subgraph2\") {\n {\n ... on U {\n __typename\n id\n }\n } =>\n {\n ... on U {\n b\n }\n }\n },\n },\n },\n },\n}" + }, + "valueCompletion": [ + { + "message": "Cannot return null for non-nullable field U.field", + "path": [ + "t", + "u" + ] + }, + { + "message": "Cannot return null for non-nullable field T.u", + "path": [ + "t", + "u" + ] + }, + { + "message": "Cannot return null for non-nullable field Query.t", + "path": [ + "t" + ] + } + ] + } +} diff --git a/apollo-router/tests/snapshots/set_context__set_context_with_null_rust_qp.snap b/apollo-router/tests/snapshots/set_context__set_context_with_null_rust_qp.snap new file mode 100644 index 0000000000..6f775414e3 --- /dev/null +++ b/apollo-router/tests/snapshots/set_context__set_context_with_null_rust_qp.snap @@ -0,0 +1,98 @@ +--- +source: apollo-router/tests/set_context.rs +expression: response +--- +{ + "data": { + "t": { + "id": "1", + "u": { + "field": 1234 + } + } + }, + "extensions": { + "apolloQueryPlan": { + "object": { + "kind": "QueryPlan", + "node": { + "kind": "Sequence", + "nodes": [ + { + "kind": "Fetch", + "serviceName": "Subgraph1", + "variableUsages": [], + "operation": "query Query_Null_Param__Subgraph1__0 { t { __typename prop id u { __typename id } } }", + "operationName": "Query_Null_Param__Subgraph1__0", + "operationKind": "query", + "id": null, + "inputRewrites": null, + "outputRewrites": null, + "contextRewrites": null, + "schemaAwareHash": "4fc423a49bbddcc8869c014934dfd128dd61a1760c4eb619940ad46f614c843b", + "authorization": { + "is_authenticated": false, + "scopes": [], + "policies": [] + } + }, + { + "kind": "Flatten", + "path": [ + "t", + "u" + ], + "node": { + "kind": "Fetch", + "serviceName": "Subgraph1", + "requires": [ + { + "kind": "InlineFragment", + "typeCondition": "U", + "selections": [ + { + "kind": "Field", + "name": "__typename" + }, + { + "kind": "Field", + "name": "id" + } + ] + } + ], + "variableUsages": [ + "contextualArgument_1_0" + ], + "operation": "query Query_Null_Param__Subgraph1__1($representations: [_Any!]!, $contextualArgument_1_0: String) { _entities(representations: $representations) { ... on U { field(a: $contextualArgument_1_0) } } }", + "operationName": "Query_Null_Param__Subgraph1__1", + "operationKind": "query", + "id": null, + "inputRewrites": null, + "outputRewrites": null, + "contextRewrites": [ + { + "kind": "KeyRenamer", + "path": [ + "..", + "... on T", + "prop" + ], + "renameKeyTo": "contextualArgument_1_0" + } + ], + "schemaAwareHash": "d863b0ef9ef616faaade4c73b2599395e074ec1521ec07634471894145e97f44", + "authorization": { + "is_authenticated": false, + "scopes": [], + "policies": [] + } + } + } + ] + } + }, + "text": "QueryPlan {\n Sequence {\n Fetch(service: \"Subgraph1\") {\n {\n t {\n __typename\n prop\n id\n u {\n __typename\n id\n }\n }\n }\n },\n Flatten(path: \"t.u\") {\n Fetch(service: \"Subgraph1\") {\n {\n ... on U {\n __typename\n id\n }\n } =>\n {\n ... on U {\n field(a: $contextualArgument_1_0)\n }\n }\n },\n },\n },\n}" + } + } +} From 491dfc9d14d7f0f264f36550ad32f660a539d9f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e?= Date: Thu, 21 Nov 2024 15:26:32 +0000 Subject: [PATCH 59/77] Revert "add errors for response validation (#5787)" (#6314) --- .../fix_geal_response_validation_errors.md | 5 - apollo-router/src/spec/query.rs | 192 +------- apollo-router/src/spec/query/tests.rs | 452 ------------------ ...__set_context_unrelated_fetch_failure.snap | 2 +- ...ntext_unrelated_fetch_failure_rust_qp.snap | 3 +- docs/source/reference/router/errors.mdx | 6 - 6 files changed, 18 insertions(+), 642 deletions(-) delete mode 100644 .changesets/fix_geal_response_validation_errors.md diff --git a/.changesets/fix_geal_response_validation_errors.md b/.changesets/fix_geal_response_validation_errors.md deleted file mode 100644 index 95fc3d60eb..0000000000 --- a/.changesets/fix_geal_response_validation_errors.md +++ /dev/null @@ -1,5 +0,0 @@ -### add errors for response validation ([Issue #5372](https://github.com/apollographql/router/issues/5372)) - -When formatting responses, the router is validating the data returned by subgraphs and replacing it with null values as appropriate. That validation phase is now adding errors when encountering the wrong type in a field requested by the client. - -By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/5787 \ No newline at end of file diff --git a/apollo-router/src/spec/query.rs b/apollo-router/src/spec/query.rs index c8bcddec6d..3ad855870a 100644 --- a/apollo-router/src/spec/query.rs +++ b/apollo-router/src/spec/query.rs @@ -30,7 +30,6 @@ use crate::json_ext::Object; use crate::json_ext::Path; use crate::json_ext::ResponsePathElement; use crate::json_ext::Value; -use crate::json_ext::ValueExt; use crate::plugins::authorization::UnauthorizedPaths; use crate::query_planner::fetch::OperationKind; use crate::query_planner::fetch::QueryHash; @@ -52,7 +51,6 @@ pub(crate) mod transform; pub(crate) mod traverse; pub(crate) const TYPENAME: &str = "__typename"; -pub(crate) const RESPONSE_VALIDATION: &str = "RESPONSE_VALIDATION_FAILED"; /// A GraphQL query. #[derive(Derivative, Serialize, Deserialize)] @@ -145,9 +143,8 @@ impl Query { let mut parameters = FormatParameters { variables: &variables, schema, - nullification_errors: Vec::new(), + errors: Vec::new(), nullified: Vec::new(), - validation_errors: Vec::new(), }; response.data = Some( @@ -164,18 +161,12 @@ impl Query { }, ); - if !parameters.nullification_errors.is_empty() { - if let Ok(value) = - serde_json_bytes::to_value(¶meters.nullification_errors) - { + if !parameters.errors.is_empty() { + if let Ok(value) = serde_json_bytes::to_value(¶meters.errors) { response.extensions.insert("valueCompletion", value); } } - if !parameters.validation_errors.is_empty() { - response.errors.append(&mut parameters.validation_errors); - } - return parameters.nullified; } None => { @@ -207,9 +198,8 @@ impl Query { let mut parameters = FormatParameters { variables: &all_variables, schema, - nullification_errors: Vec::new(), + errors: Vec::new(), nullified: Vec::new(), - validation_errors: Vec::new(), }; response.data = Some( @@ -225,18 +215,12 @@ impl Query { Err(InvalidValue) => Value::Null, }, ); - if !parameters.nullification_errors.is_empty() { - if let Ok(value) = - serde_json_bytes::to_value(¶meters.nullification_errors) - { + if !parameters.errors.is_empty() { + if let Ok(value) = serde_json_bytes::to_value(¶meters.errors) { response.extensions.insert("valueCompletion", value); } } - if !parameters.validation_errors.is_empty() { - response.errors.append(&mut parameters.validation_errors); - } - return parameters.nullified; } } @@ -358,7 +342,6 @@ impl Query { output: &mut Value, path: &mut Vec>, parent_type: &executable::Type, - field_or_index: FieldOrIndex<'a>, selection_set: &'a [Selection], ) -> Result<(), InvalidValue> { // for every type, if we have an invalid value, we will replace it with null @@ -379,8 +362,7 @@ impl Query { input, output, path, - parent_type, - field_or_index, + field_type, selection_set, ) { Err(_) => Err(InvalidValue), @@ -395,7 +377,7 @@ impl Query { ), _ => todo!(), }; - parameters.nullification_errors.push(Error { + parameters.errors.push(Error { message, path: Some(Path::from_response_slice(path)), ..Error::default() @@ -435,7 +417,6 @@ impl Query { &mut output_array[i], path, field_type, - FieldOrIndex::Index(i), selection_set, ); path.pop(); @@ -449,22 +430,7 @@ impl Query { Ok(()) => Ok(()), } } - Value::Null => Ok(()), - v => { - parameters.validation_errors.push( - Error::builder() - .message(format!( - "Invalid non-list value of type {} for list type {field_type}", - v.json_type_name() - )) - .path(Path::from_response_slice(path)) - .extension_code(RESPONSE_VALIDATION) - .build(), - ); - - *output = Value::Null; - Ok(()) - } + _ => Ok(()), }, executable::Type::Named(name) if name == "Int" => { let opt = if input.is_i64() { @@ -480,19 +446,6 @@ impl Query { if opt.is_some() { *output = input.clone(); } else { - if !input.is_null() { - parameters.validation_errors.push( - Error::builder() - .message(invalid_value_message( - parent_type, - field_type, - field_or_index, - )) - .path(Path::from_response_slice(path)) - .extension_code(RESPONSE_VALIDATION) - .build(), - ); - } *output = Value::Null; } Ok(()) @@ -501,19 +454,6 @@ impl Query { if input.as_f64().is_some() { *output = input.clone(); } else { - if !input.is_null() { - parameters.validation_errors.push( - Error::builder() - .message(invalid_value_message( - parent_type, - field_type, - field_or_index, - )) - .path(Path::from_response_slice(path)) - .extension_code(RESPONSE_VALIDATION) - .build(), - ); - } *output = Value::Null; } Ok(()) @@ -522,19 +462,6 @@ impl Query { if input.as_bool().is_some() { *output = input.clone(); } else { - if !input.is_null() { - parameters.validation_errors.push( - Error::builder() - .message(invalid_value_message( - parent_type, - field_type, - field_or_index, - )) - .path(Path::from_response_slice(path)) - .extension_code(RESPONSE_VALIDATION) - .build(), - ); - } *output = Value::Null; } Ok(()) @@ -543,19 +470,6 @@ impl Query { if input.as_str().is_some() { *output = input.clone(); } else { - if !input.is_null() { - parameters.validation_errors.push( - Error::builder() - .message(invalid_value_message( - parent_type, - field_type, - field_or_index, - )) - .path(Path::from_response_slice(path)) - .extension_code(RESPONSE_VALIDATION) - .build(), - ); - } *output = Value::Null; } Ok(()) @@ -564,19 +478,6 @@ impl Query { if input.is_string() || input.is_i64() || input.is_u64() || input.is_f64() { *output = input.clone(); } else { - if !input.is_null() { - parameters.validation_errors.push( - Error::builder() - .message(invalid_value_message( - parent_type, - field_type, - field_or_index, - )) - .path(Path::from_response_slice(path)) - .extension_code(RESPONSE_VALIDATION) - .build(), - ); - } *output = Value::Null; } Ok(()) @@ -596,31 +497,11 @@ impl Query { *output = input.clone(); Ok(()) } else { - parameters.validation_errors.push( - Error::builder() - .message(format!( - "Expected a valid enum value for type {}", - enum_type.name - )) - .path(Path::from_response_slice(path)) - .extension_code(RESPONSE_VALIDATION) - .build(), - ); *output = Value::Null; Ok(()) } } None => { - parameters.validation_errors.push( - Error::builder() - .message(format!( - "Expected a valid enum value for type {}", - enum_type.name - )) - .path(Path::from_response_slice(path)) - .extension_code(RESPONSE_VALIDATION) - .build(), - ); *output = Value::Null; Ok(()) } @@ -631,9 +512,6 @@ impl Query { match input { Value::Object(ref mut input_object) => { - // FIXME: we should return an error if __typename is not a string - // but this might cause issues for some production deployments where - // __typename might be missing or invalid (cf https://github.com/apollographql/router/commit/4a592f4933b7b9e46f14c7a98404b9e067687f09 ) if let Some(input_type) = input_object.get(TYPENAME).and_then(|val| val.as_str()) { @@ -686,20 +564,8 @@ impl Query { Ok(()) } - Value::Null => { - *output = Value::Null; - Ok(()) - } - v => { - parameters.validation_errors.push( - Error::builder() - .message(format!( - "Invalid non-object value of type {} for composite type {type_name}", v.json_type_name() - )) - .path(Path::from_response_slice(path)) - .extension_code(RESPONSE_VALIDATION) - .build(), - ); + _ => { + parameters.nullified.push(Path::from_response_slice(path)); *output = Value::Null; Ok(()) } @@ -775,7 +641,6 @@ impl Query { output_value, path, current_type, - FieldOrIndex::Field(field_name.as_str()), selection_set, ); path.pop(); @@ -785,7 +650,7 @@ impl Query { output.insert((*field_name).clone(), Value::Null); } if field_type.is_non_null() { - parameters.nullification_errors.push(Error { + parameters.errors.push(Error { message: format!( "Cannot return null for non-nullable field {current_type}.{}", field_name.as_str() @@ -907,11 +772,6 @@ impl Query { continue; } - let root_type = apollo_compiler::ast::Type::Named( - // Unchecked name instantiation is always safe, and we know the name is - // valid here - apollo_compiler::Name::new_unchecked(root_type_name), - ); let field_name = alias.as_ref().unwrap_or(name); let field_name_str = field_name.as_str(); @@ -940,14 +800,13 @@ impl Query { input_value, output_value, path, - &root_type, - FieldOrIndex::Field(field_name_str), + &field_type.0, selection_set, ); path.pop(); res? } else if field_type.is_non_null() { - parameters.nullification_errors.push(Error { + parameters.errors.push(Error { message: format!( "Cannot return null for non-nullable field {}.{field_name_str}", root_type_name @@ -1155,8 +1014,7 @@ impl Query { /// Intermediate structure for arguments passed through the entire formatting struct FormatParameters<'a> { variables: &'a Object, - nullification_errors: Vec, - validation_errors: Vec, + errors: Vec, nullified: Vec, schema: &'a ApiSchema, } @@ -1176,26 +1034,6 @@ pub(crate) struct Variable { default_value: Option, } -enum FieldOrIndex<'a> { - Field(&'a str), - Index(usize), -} - -fn invalid_value_message( - parent_type: &executable::Type, - field_type: &executable::Type, - field_or_index: FieldOrIndex, -) -> String { - match field_or_index { - FieldOrIndex::Field(field_name) => { - format!("Invalid value found for field {parent_type}.{field_name}") - } - FieldOrIndex::Index(i) => { - format!("Invalid value found for array element of type {field_type} at index {i}") - } - } -} - impl Operation { fn empty() -> Self { Self { diff --git a/apollo-router/src/spec/query/tests.rs b/apollo-router/src/spec/query/tests.rs index f9af994874..1d97962405 100644 --- a/apollo-router/src/spec/query/tests.rs +++ b/apollo-router/src/spec/query/tests.rs @@ -40,7 +40,6 @@ macro_rules! assert_eq_and_ordered_json { } #[derive(Default)] -#[must_use = "Must call .test() to run the test"] struct FormatTest { schema: Option<&'static str>, query_type_name: Option<&'static str>, @@ -101,11 +100,6 @@ impl FormatTest { self } - fn expected_errors(mut self, v: serde_json_bytes::Value) -> Self { - self.expected_errors = Some(v); - self - } - fn expected_extensions(mut self, v: serde_json_bytes::Value) -> Self { self.expected_extensions = Some(v); self @@ -1188,452 +1182,6 @@ fn reformat_response_array_of_id_duplicate() { .test(); } -#[test] -// If this test fails, this means you got greedy about allocations, -// beware of aliases! -fn reformat_response_expected_types() { - FormatTest::builder() - .schema( - "type Query { - get: Thing - } - type Thing { - i: Int - s: String - f: Float - b: Boolean - e: E - u: U - id: ID - l: [Int] - } - - enum E { - A - B - } - union U = ObjA | ObjB - type ObjA { - a: String - } - type ObjB { - a: String - } - ", - ) - .query( - r#"{ - get { - i - s - f - ... on Thing { - b - e - u { - ... on ObjA { - a - } - } - id - } - l - } - }"#, - ) - .response(json! {{ - "get": { - "i": "hello", - "s": 1.0, - "f": [1], - "b": 0, - "e": "X", - "u": 1, - "id": { - "test": "test", - }, - "l": "A" - }, - }}) - .expected(json! {{ - "get": { - "i": null, - "s": null, - "f": null, - "b": null, - "e": null, - "u": null, - // FIXME(@goto-bus-stop): this should be null, but we do not - // validate ID values today - "id": { - "test": "test", - }, - "l": null - }, - }}) - .expected_errors(json! ([ - { - "message": "Invalid value found for field Thing.i", - "path": ["get", "i"], - "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - }, - { - "message": "Invalid value found for field Thing.s", - "path": ["get", "s"], - "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - }, - { - "message": "Invalid value found for field Thing.f", - "path": ["get", "f"], - "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - }, - { - "message": "Invalid value found for field Thing.b", - "path": ["get", "b"], - "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - }, - { - "message": "Expected a valid enum value for type E", - "path": ["get", "e"], - "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - }, - { - "message": "Invalid non-object value of type number for composite type U", - "path": ["get", "u"], - "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - }, - { - "message": "Invalid non-list value of type string for list type [Int]", - "path": ["get", "l"], - "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - } - ])) - .test(); -} - -#[test] -fn reformat_response_expected_int() { - FormatTest::builder() - .schema( - r#" - type Query { - a: Int - b: Int - c: Int - d: Int - e: Int - f: Int - g: Int - } - "#, - ) - .query(r#"{ a b c d e f g }"#) - .response(json!({ - "a": 1, - "b": 1.0, // Should be accepted as Int 1 - "c": 1.2, // Float should not be truncated - "d": "1234", // Optional to be coerced by spec: we do not do so - "e": true, - "f": [1], - "g": { "value": 1 }, - })) - .expected(json!({ - "a": 1, - // FIXME(@goto-bus-stop): we should accept this, and truncate it - // to Int value `1`, but do not do so today - "b": null, - "c": null, - "d": null, - "e": null, - "f": null, - "g": null, - })) - .expected_errors(json!([ - { - "message": "Invalid value found for field Query.b", - "path": ["b"], - "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - }, - { - "message": "Invalid value found for field Query.c", - "path": ["c"], - "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - }, - { - "message": "Invalid value found for field Query.d", - "path": ["d"], - "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - }, - { - "message": "Invalid value found for field Query.e", - "path": ["e"], - "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - }, - { - "message": "Invalid value found for field Query.f", - "path": ["f"], - "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - }, - { - "message": "Invalid value found for field Query.g", - "path": ["g"], - "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - }, - ])) - .test(); -} - -#[test] -fn reformat_response_expected_int_range() { - let schema = "type Query { - me: User - } - - type User { - id: String! - name: String - someNumber: Int - someOtherNumber: Int! - } - "; - - let query = "query { me { id name someNumber } }"; - - FormatTest::builder() - .schema(schema) - .query(query) - .response(json!({ - "me": { - "id": "123", - "name": "Guy Guyson", - "someNumber": 51049694213_i64 - }, - })) - .expected(json!({ - "me": { - "id": "123", - "name": "Guy Guyson", - "someNumber": null, - }, - })) - .expected_errors(json!([ - { - "message": "Invalid value found for field User.someNumber", - "path": ["me", "someNumber"], - "extensions": { "code": "RESPONSE_VALIDATION_FAILED" }, - } - ])) - .test(); - - let query2 = "query { me { id name someOtherNumber } }"; - - FormatTest::builder() - .schema(schema) - .query(query2) - .response(json!({ - "me": { - "id": "123", - "name": "Guy Guyson", - "someOtherNumber": 51049694213_i64 - }, - })) - .expected(json!({ - "me": null, - })) - .expected_errors(json!([ - { - "message": "Invalid value found for field User.someOtherNumber", - "path": ["me", "someOtherNumber"], - "extensions": { "code": "RESPONSE_VALIDATION_FAILED" }, - }, - ])) - .test(); -} - -#[test] -fn reformat_response_expected_float() { - FormatTest::builder() - .schema( - r#" - type Query { - a: Float - b: Float - c: Float - d: Float - e: Float - f: Float - } - "#, - ) - .query(r#"{ a b c d e f }"#) - .response(json!({ - // Note: NaNs and Infinitys are not supported by GraphQL Floats, - // and handily not representable in JSON, so we don't need to handle them. - "a": 1, // Int can be interpreted as Float - "b": 1.2, - "c": "2.2", // Optional to be coerced by spec: we do not do so - "d": true, - "e": [1.234], - "f": { "value": 12.34 }, - })) - .expected(json!({ - "a": 1, // Representing int-valued float without the decimals is okay in JSON - "b": 1.2, - "c": null, - "d": null, - "e": null, - "f": null, - })) - .expected_errors(json!([ - { - "message": "Invalid value found for field Query.c", - "path": ["c"], - "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - }, - { - "message": "Invalid value found for field Query.d", - "path": ["d"], - "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - }, - { - "message": "Invalid value found for field Query.e", - "path": ["e"], - "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - }, - { - "message": "Invalid value found for field Query.f", - "path": ["f"], - "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - }, - ])) - .test(); -} - -#[test] -fn reformat_response_expected_string() { - FormatTest::builder() - .schema( - r#" - type Query { - a: String - b: String - c: String - d: String - e: String - f: String - } - "#, - ) - .query(r#"{ a b c d e f }"#) - .response(json!({ - "a": "text", - "b": 1, // Optional to be coerced by spec: we do not do so - "c": false, // Optional to be coerced by spec: we do not do so - "d": 1234.5678, // Optional to be coerced by spec: we do not do so - "e": ["s"], - "f": { "text": "text" }, - })) - .expected(json!({ - "a": "text", - "b": null, - "c": null, - "d": null, - "e": null, - "f": null, - })) - .expected_errors(json!([ - { - "message": "Invalid value found for field Query.b", - "path": ["b"], - "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - }, - { - "message": "Invalid value found for field Query.c", - "path": ["c"], - "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - }, - { - "message": "Invalid value found for field Query.d", - "path": ["d"], - "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - }, - { - "message": "Invalid value found for field Query.e", - "path": ["e"], - "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - }, - { - "message": "Invalid value found for field Query.f", - "path": ["f"], - "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - }, - ])) - .test(); -} - -#[test] -fn reformat_response_expected_id() { - FormatTest::builder() - .schema( - r#" - type Query { - a: ID - b: ID - c: ID - d: ID - e: ID - f: ID - g: ID - } - "#, - ) - .query(r#"{ a b c d e f g }"#) - .response(json!({ - "a": "1234", - "b": "ABCD", - "c": 1234, - "d": 1234.0, // Integer represented as a float should be coerced - "e": false, - "f": 1234.5678, // Float should not be truncated - "g": ["s"], - })) - .expected(json!({ - // Note technically IDs should always be represented as a String in JSON, - // though the value returned from a field can be either Int or String. - // We do not coerce the acceptable types to strings today. - "a": "1234", - "b": "ABCD", - "c": 1234, - // FIXME(@goto-bus-stop): We should coerce this to string "1234" (without .0), - // but we don't do so today - "d": 1234.0, - // FIXME(@goto-bus-stop): We should null out all these values, - // but we don't validate IDs today - "e": false, - "f": 1234.5678, - "g": ["s"], - })) - .expected_errors(json!([ - // FIXME(@goto-bus-stop): we should expect these errors: - // { - // "message": "Invalid value found for field Query.e", - // "path": ["e"], - // "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - // }, - // { - // "message": "Invalid value found for field Query.f", - // "path": ["f"], - // "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - // }, - // { - // "message": "Invalid value found for field Query.g", - // "path": ["g"], - // "extensions": { "code": "RESPONSE_VALIDATION_FAILED" } - // }, - ])) - .test(); -} - #[test] fn solve_query_with_single_typename() { FormatTest::builder() diff --git a/apollo-router/tests/snapshots/set_context__set_context_unrelated_fetch_failure.snap b/apollo-router/tests/snapshots/set_context__set_context_unrelated_fetch_failure.snap index 3232f642c0..ead3b10258 100644 --- a/apollo-router/tests/snapshots/set_context__set_context_unrelated_fetch_failure.snap +++ b/apollo-router/tests/snapshots/set_context__set_context_unrelated_fetch_failure.snap @@ -163,7 +163,7 @@ expression: response ] }, { - "message": "Cannot return null for non-nullable field Query.t", + "message": "Cannot return null for non-nullable field T!.t", "path": [ "t" ] diff --git a/apollo-router/tests/snapshots/set_context__set_context_unrelated_fetch_failure_rust_qp.snap b/apollo-router/tests/snapshots/set_context__set_context_unrelated_fetch_failure_rust_qp.snap index b8650bb7bb..8194cfc237 100644 --- a/apollo-router/tests/snapshots/set_context__set_context_unrelated_fetch_failure_rust_qp.snap +++ b/apollo-router/tests/snapshots/set_context__set_context_unrelated_fetch_failure_rust_qp.snap @@ -1,6 +1,7 @@ --- source: apollo-router/tests/set_context.rs expression: response +snapshot_kind: text --- { "data": null, @@ -161,7 +162,7 @@ expression: response ] }, { - "message": "Cannot return null for non-nullable field Query.t", + "message": "Cannot return null for non-nullable field T!.t", "path": [ "t" ] diff --git a/docs/source/reference/router/errors.mdx b/docs/source/reference/router/errors.mdx index 6878ea20e0..aff203ecf4 100644 --- a/docs/source/reference/router/errors.mdx +++ b/docs/source/reference/router/errors.mdx @@ -98,10 +98,4 @@ The query could not be parsed. The response from a subgraph did not match the GraphQL schema. - - -A subgraph returned a field with a different type that mandated by the GraphQL schema. - - - From d26ea8baf123d9eb834af52bb5347ee28b107260 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Thu, 21 Nov 2024 17:43:40 +0200 Subject: [PATCH 60/77] prep release: v1.58.0-rc.1 --- Cargo.lock | 8 ++++---- apollo-federation/Cargo.toml | 2 +- apollo-router-benchmarks/Cargo.toml | 2 +- apollo-router-scaffold/Cargo.toml | 2 +- apollo-router-scaffold/templates/base/Cargo.template.toml | 2 +- .../templates/base/xtask/Cargo.template.toml | 2 +- apollo-router/Cargo.toml | 4 ++-- dockerfiles/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 | 6 +++--- scripts/install.sh | 2 +- 13 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9fde13394b..a774605d8d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -178,7 +178,7 @@ dependencies = [ [[package]] name = "apollo-federation" -version = "1.58.0-rc.0" +version = "1.58.0-rc.1" dependencies = [ "apollo-compiler", "derive_more", @@ -231,7 +231,7 @@ dependencies = [ [[package]] name = "apollo-router" -version = "1.58.0-rc.0" +version = "1.58.0-rc.1" dependencies = [ "access-json", "ahash", @@ -399,7 +399,7 @@ dependencies = [ [[package]] name = "apollo-router-benchmarks" -version = "1.58.0-rc.0" +version = "1.58.0-rc.1" dependencies = [ "apollo-parser", "apollo-router", @@ -415,7 +415,7 @@ dependencies = [ [[package]] name = "apollo-router-scaffold" -version = "1.58.0-rc.0" +version = "1.58.0-rc.1" dependencies = [ "anyhow", "cargo-scaffold", diff --git a/apollo-federation/Cargo.toml b/apollo-federation/Cargo.toml index 7f5d39efc7..b5cdc10eea 100644 --- a/apollo-federation/Cargo.toml +++ b/apollo-federation/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-federation" -version = "1.58.0-rc.0" +version = "1.58.0-rc.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 1a516d25f8..0ab7b28d81 100644 --- a/apollo-router-benchmarks/Cargo.toml +++ b/apollo-router-benchmarks/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router-benchmarks" -version = "1.58.0-rc.0" +version = "1.58.0-rc.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 0e35a1180e..0bd3288ce7 100644 --- a/apollo-router-scaffold/Cargo.toml +++ b/apollo-router-scaffold/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router-scaffold" -version = "1.58.0-rc.0" +version = "1.58.0-rc.1" authors = ["Apollo Graph, Inc. "] edition = "2021" license = "Elastic-2.0" diff --git a/apollo-router-scaffold/templates/base/Cargo.template.toml b/apollo-router-scaffold/templates/base/Cargo.template.toml index 0a82428fc1..39e29486c5 100644 --- a/apollo-router-scaffold/templates/base/Cargo.template.toml +++ b/apollo-router-scaffold/templates/base/Cargo.template.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.58.0-rc.0" +apollo-router = "1.58.0-rc.1" {{/if}} {{/if}} async-trait = "0.1.52" diff --git a/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml b/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml index 1fb3c2ce4a..6194824517 100644 --- a/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml +++ b/apollo-router-scaffold/templates/base/xtask/Cargo.template.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.58.0-rc.0" } +apollo-router-scaffold = { git = "https://github.com/apollographql/router.git", tag = "v1.58.0-rc.1" } {{/if}} {{/if}} anyhow = "1.0.58" diff --git a/apollo-router/Cargo.toml b/apollo-router/Cargo.toml index 77f41071b5..714091c7a2 100644 --- a/apollo-router/Cargo.toml +++ b/apollo-router/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router" -version = "1.58.0-rc.0" +version = "1.58.0-rc.1" authors = ["Apollo Graph, Inc. "] repository = "https://github.com/apollographql/router/" documentation = "https://docs.rs/apollo-router" @@ -66,7 +66,7 @@ features = ["docs_rs"] access-json = "0.1.0" anyhow = "1.0.86" apollo-compiler.workspace = true -apollo-federation = { path = "../apollo-federation", version = "=1.58.0-rc.0" } +apollo-federation = { path = "../apollo-federation", version = "=1.58.0-rc.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 6ce00496e3..945275f990 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.58.0-rc.0 + image: ghcr.io/apollographql/router:v1.58.0-rc.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 5d07c9c245..dc597b7ad8 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.58.0-rc.0 + image: ghcr.io/apollographql/router:v1.58.0-rc.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 00ae0bd2e0..95c35e5dff 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.58.0-rc.0 + image: ghcr.io/apollographql/router:v1.58.0-rc.1 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 ef9327ee8b..c4b5f49fcb 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.58.0-rc.0 +version: 1.58.0-rc.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.58.0-rc.0" +appVersion: "v1.58.0-rc.1" diff --git a/helm/chart/router/README.md b/helm/chart/router/README.md index 12e17400da..21c73d3a24 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.58.0-rc.0](https://img.shields.io/badge/Version-1.58.0--rc.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.58.0-rc.0](https://img.shields.io/badge/AppVersion-v1.58.0--rc.0-informational?style=flat-square) +![Version: 1.58.0-rc.1](https://img.shields.io/badge/Version-1.58.0--rc.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.58.0-rc.1](https://img.shields.io/badge/AppVersion-v1.58.0--rc.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.58.0-rc.0 +helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0-rc.1 ``` ## Install Chart @@ -19,7 +19,7 @@ helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0-rc.0 **Important:** only helm3 is supported ```console -helm upgrade --install [RELEASE_NAME] oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0-rc.0 --values my-values.yaml +helm upgrade --install [RELEASE_NAME] oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0-rc.1 --values my-values.yaml ``` _See [configuration](#configuration) below._ diff --git a/scripts/install.sh b/scripts/install.sh index 95b4f39944..d695ff2cb8 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.58.0-rc.0" +PACKAGE_VERSION="v1.58.0-rc.1" download_binary() { downloader --check From df41dd4debb3d10f85a17b42fbc6d20c3d77abf6 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Thu, 21 Nov 2024 18:14:44 +0200 Subject: [PATCH 61/77] ci: Remove "test_updated" from release workflows (#6312) Co-authored-by: Dylan Anthony --- .circleci/config.yml | 127 +++++++++++++++++++++++++++++-------------- 1 file changed, 86 insertions(+), 41 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7b932c7fc3..011910e56e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -55,9 +55,9 @@ executors: # See https://circleci.com/docs/xcode-policy along with the support matrix # at https://circleci.com/docs/using-macos#supported-xcode-versions. # We use the major.minor notation to bring in compatible patches. - # + # # TODO: remove workaround added in https://github.com/apollographql/router/pull/5462 - # once we update to Xcode >= 15.1.0 + # once we update to Xcode >= 15.1.0 # See: https://github.com/apollographql/router/pull/5462 xcode: "14.2.0" resource_class: macos.m1.large.gen1 @@ -93,6 +93,9 @@ parameters: quick_nightly: type: boolean default: false + test_updated_cargo_deps: + type: boolean + default: false # These are common environment variables that we want to set on on all jobs. # While these could conceivably be set on the CircleCI project settings' @@ -504,7 +507,7 @@ commands: # Use the settings from the "ci" profile in nextest configuration. NEXTEST_PROFILE: ci # Temporary disable lib backtrace since it crashing on MacOS - # TODO: remove this workaround once we update to Xcode >= 15.1.0 + # TODO: remove this workaround once we update to Xcode >= 15.1.0 # See: https://github.com/apollographql/router/pull/5462 RUST_LIB_BACKTRACE: 0 command: xtask test --workspace --locked --features ci,hyper_header_limits @@ -599,6 +602,10 @@ jobs: parameters: platform: type: executor + default: amd_linux_test + from_test_updated_cargo_deps_workflow: + type: boolean + default: false executor: << parameters.platform >> steps: - checkout @@ -611,6 +618,67 @@ jobs: cargo fetch - xtask_test: variant: "updated" + + - when: + condition: + equal: [ true, << parameters.from_test_updated_cargo_deps_workflow >> ] + steps: + - slack/notify: + event: fail + custom: | + { + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": ":x: The `test_updated_cargo_deps` workflow has **failed** for `${CIRCLE_JOB}` on `${CIRCLE_PROJECT_REPONAME}`'s `${CIRCLE_BRANCH}`!" + } + }, + { + "type": "actions", + "elements": [ + { + "type": "button", + "action_id": "success_tagged_deploy_view", + "text": { + "type": "plain_text", + "text": "View Job" + }, + "url": "${CIRCLE_BUILD_URL}" + } + ] + } + ] + } + - slack/notify: + event: pass + custom: | + { + "blocks": [ + { + "type": "section", + "text": { + "type": "mrkdwn", + "text": ":white_check_mark: The `test_updated_cargo_deps` workflow has passed for `${CIRCLE_JOB}` on `${CIRCLE_PROJECT_REPONAME}`'s `${CIRCLE_BRANCH}`." + } + }, + { + "type": "actions", + "elements": [ + { + "type": "button", + "action_id": "success_tagged_deploy_view", + "text": { + "type": "plain_text", + "text": "View Job" + }, + "url": "${CIRCLE_BUILD_URL}" + } + ] + } + ] + } pre_verify_release: environment: <<: *common_job_environment @@ -750,20 +818,20 @@ jobs: command: | # Source of the new image will be ser to the repo URL. # This will have the effect of setting org.opencontainers.image.source and org.opencontainers.image.author to the originating pipeline - # Therefore the docker image will have the same permissions as the originating project. + # Therefore the docker image will have the same permissions as the originating project. # See: https://docs.github.com/en/packages/learn-github-packages/connecting-a-repository-to-a-package#connecting-a-repository-to-a-container-image-using-the-command-line - + BASE_VERSION=$(cargo metadata --format-version=1 --no-deps | jq --raw-output '.packages[0].version') ARTIFACT_URL="https://output.circle-artifacts.com/output/job/${CIRCLE_WORKFLOW_JOB_ID}/artifacts/0/artifacts/router-v${BASE_VERSION}-x86_64-unknown-linux-gnu.tar.gz" VERSION="v$(echo "${BASE_VERSION}" | tr "+" "-")" ROUTER_TAG=ghcr.io/apollographql/nightly/router - + echo "REPO_URL: ${REPO_URL}" echo "BASE_VERSION: ${BASE_VERSION}" echo "ARTIFACT_URL: ${ARTIFACT_URL}" echo "VERSION: ${VERSION}" echo "ROUTER_TAG: ${ROUTER_TAG}" - + # Create a multi-arch builder which works properly under qemu docker run --rm --privileged multiarch/qemu-user-static --reset -p yes docker context create buildx-build @@ -948,12 +1016,19 @@ jobs: helm push ${CHART} oci://ghcr.io/apollographql/helm-charts workflows: + test_updated_cargo_deps: + when: << pipeline.parameters.test_updated_cargo_deps >> + jobs: + - test_updated: + platform: amd_linux_test + from_test_updated_cargo_deps_workflow: true ci_checks: when: not: or: - << pipeline.parameters.nightly >> - << pipeline.parameters.quick_nightly >> + - << pipeline.parameters.test_updated_cargo_deps >> jobs: - lint: matrix: @@ -967,16 +1042,6 @@ workflows: matrix: parameters: platform: [ amd_linux_build ] - - - test_updated: - requires: - - lint - - check_helm - - check_compliance - matrix: - parameters: - platform: - [ amd_linux_test ] - test: # this should be changed back to true on dev after release fuzz: false @@ -1016,21 +1081,9 @@ workflows: matrix: parameters: platform: [ amd_linux_build ] - - - test_updated: - requires: - - lint - - check_helm - - check_compliance - matrix: - parameters: - platform: - [ amd_linux_test ] - test: requires: - lint - - check_helm - - check_compliance matrix: parameters: platform: @@ -1038,7 +1091,8 @@ workflows: - build_release: requires: - test - - test_updated + - check_helm + - check_compliance nightly: true context: - router @@ -1073,6 +1127,7 @@ workflows: or: - << pipeline.parameters.nightly >> - << pipeline.parameters.quick_nightly >> + - << pipeline.parameters.test_updated_cargo_deps >> jobs: - pre_verify_release: matrix: @@ -1110,16 +1165,6 @@ workflows: ignore: /.*/ tags: only: /v.*/ - - test_updated: - matrix: - parameters: - platform: - [ amd_linux_test ] - filters: - branches: - ignore: /.*/ - tags: - only: /v.*/ - test: matrix: parameters: @@ -1148,7 +1193,6 @@ workflows: - check_compliance - pre_verify_release - test - - test_updated filters: branches: ignore: /.*/ @@ -1161,6 +1205,7 @@ workflows: or: - << pipeline.parameters.nightly >> - << pipeline.parameters.quick_nightly >> + - << pipeline.parameters.test_updated_cargo_deps >> jobs: - secops/gitleaks: context: From c68814f34c37dc98e3437d3a6a888e987f5ca9a1 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Thu, 21 Nov 2024 19:55:53 +0200 Subject: [PATCH 62/77] prep release: v1.58.0-rc.2 --- Cargo.lock | 8 ++++---- apollo-federation/Cargo.toml | 2 +- apollo-router-benchmarks/Cargo.toml | 2 +- apollo-router-scaffold/Cargo.toml | 2 +- apollo-router-scaffold/templates/base/Cargo.template.toml | 2 +- .../templates/base/xtask/Cargo.template.toml | 2 +- apollo-router/Cargo.toml | 4 ++-- dockerfiles/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 | 6 +++--- scripts/install.sh | 2 +- 13 files changed, 20 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a774605d8d..34e2c836de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -178,7 +178,7 @@ dependencies = [ [[package]] name = "apollo-federation" -version = "1.58.0-rc.1" +version = "1.58.0-rc.2" dependencies = [ "apollo-compiler", "derive_more", @@ -231,7 +231,7 @@ dependencies = [ [[package]] name = "apollo-router" -version = "1.58.0-rc.1" +version = "1.58.0-rc.2" dependencies = [ "access-json", "ahash", @@ -399,7 +399,7 @@ dependencies = [ [[package]] name = "apollo-router-benchmarks" -version = "1.58.0-rc.1" +version = "1.58.0-rc.2" dependencies = [ "apollo-parser", "apollo-router", @@ -415,7 +415,7 @@ dependencies = [ [[package]] name = "apollo-router-scaffold" -version = "1.58.0-rc.1" +version = "1.58.0-rc.2" dependencies = [ "anyhow", "cargo-scaffold", diff --git a/apollo-federation/Cargo.toml b/apollo-federation/Cargo.toml index b5cdc10eea..e0e8b9150c 100644 --- a/apollo-federation/Cargo.toml +++ b/apollo-federation/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-federation" -version = "1.58.0-rc.1" +version = "1.58.0-rc.2" 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 0ab7b28d81..34410cad70 100644 --- a/apollo-router-benchmarks/Cargo.toml +++ b/apollo-router-benchmarks/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router-benchmarks" -version = "1.58.0-rc.1" +version = "1.58.0-rc.2" 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 0bd3288ce7..105b1ce0bd 100644 --- a/apollo-router-scaffold/Cargo.toml +++ b/apollo-router-scaffold/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router-scaffold" -version = "1.58.0-rc.1" +version = "1.58.0-rc.2" authors = ["Apollo Graph, Inc. "] edition = "2021" license = "Elastic-2.0" diff --git a/apollo-router-scaffold/templates/base/Cargo.template.toml b/apollo-router-scaffold/templates/base/Cargo.template.toml index 39e29486c5..0a181f0008 100644 --- a/apollo-router-scaffold/templates/base/Cargo.template.toml +++ b/apollo-router-scaffold/templates/base/Cargo.template.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.58.0-rc.1" +apollo-router = "1.58.0-rc.2" {{/if}} {{/if}} async-trait = "0.1.52" diff --git a/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml b/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml index 6194824517..e81afd56d8 100644 --- a/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml +++ b/apollo-router-scaffold/templates/base/xtask/Cargo.template.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.58.0-rc.1" } +apollo-router-scaffold = { git = "https://github.com/apollographql/router.git", tag = "v1.58.0-rc.2" } {{/if}} {{/if}} anyhow = "1.0.58" diff --git a/apollo-router/Cargo.toml b/apollo-router/Cargo.toml index 714091c7a2..ab3a737fd0 100644 --- a/apollo-router/Cargo.toml +++ b/apollo-router/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router" -version = "1.58.0-rc.1" +version = "1.58.0-rc.2" authors = ["Apollo Graph, Inc. "] repository = "https://github.com/apollographql/router/" documentation = "https://docs.rs/apollo-router" @@ -66,7 +66,7 @@ features = ["docs_rs"] access-json = "0.1.0" anyhow = "1.0.86" apollo-compiler.workspace = true -apollo-federation = { path = "../apollo-federation", version = "=1.58.0-rc.1" } +apollo-federation = { path = "../apollo-federation", version = "=1.58.0-rc.2" } 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 945275f990..1f9bc33cb9 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.58.0-rc.1 + image: ghcr.io/apollographql/router:v1.58.0-rc.2 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 dc597b7ad8..0a22a025e4 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.58.0-rc.1 + image: ghcr.io/apollographql/router:v1.58.0-rc.2 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 95c35e5dff..d6230610f5 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.58.0-rc.1 + image: ghcr.io/apollographql/router:v1.58.0-rc.2 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 c4b5f49fcb..7ff3a8b8f7 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.58.0-rc.1 +version: 1.58.0-rc.2 # 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.58.0-rc.1" +appVersion: "v1.58.0-rc.2" diff --git a/helm/chart/router/README.md b/helm/chart/router/README.md index 21c73d3a24..15e2be484d 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.58.0-rc.1](https://img.shields.io/badge/Version-1.58.0--rc.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.58.0-rc.1](https://img.shields.io/badge/AppVersion-v1.58.0--rc.1-informational?style=flat-square) +![Version: 1.58.0-rc.2](https://img.shields.io/badge/Version-1.58.0--rc.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.58.0-rc.2](https://img.shields.io/badge/AppVersion-v1.58.0--rc.2-informational?style=flat-square) ## Prerequisites @@ -11,7 +11,7 @@ ## Get Repo Info ```console -helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0-rc.1 +helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0-rc.2 ``` ## Install Chart @@ -19,7 +19,7 @@ helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0-rc.1 **Important:** only helm3 is supported ```console -helm upgrade --install [RELEASE_NAME] oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0-rc.1 --values my-values.yaml +helm upgrade --install [RELEASE_NAME] oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0-rc.2 --values my-values.yaml ``` _See [configuration](#configuration) below._ diff --git a/scripts/install.sh b/scripts/install.sh index d695ff2cb8..a1b50a9ae3 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.58.0-rc.1" +PACKAGE_VERSION="v1.58.0-rc.2" download_binary() { downloader --check From b3a7cfed271b1e78a05226996d5e200224a7df94 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Mon, 25 Nov 2024 14:57:05 +0200 Subject: [PATCH 63/77] Apply suggestions from changelog editorial Co-authored-by: Edward Huang --- ...arify_authorization_directive_composition.md | 5 +++-- .changesets/feat_add_dns_resolution_strategy.md | 10 ++++++---- .changesets/feat_error_extensions_service.md | 9 ++++++--- .changesets/feat_geal_subgraph_request_id.md | 5 +++-- ...nable_generate_query_fragments_by_default.md | 17 +++++------------ .changesets/feat_max_headers.md | 6 +++--- .changesets/feat_router_528_impl_set_context.md | 2 +- .changesets/fix_bryn_fix_header_propagation.md | 8 ++++---- .../fix_fix_file_upload_variable_placeholder.md | 6 +++--- ...ypen_log_less_error_for_subgraph_batching.md | 6 ++---- .../fix_geal_deduplication_processing_time.md | 4 ++-- .changesets/fix_geal_introspection_dedup_fix.md | 4 ++-- .changesets/fix_renee_limit_errors.md | 5 ++--- .changesets/fix_simon_compute_jobs.md | 6 ++++-- ...ninesling_demand_control_variable_scoring.md | 6 ++++-- .../fix_tninesling_typename_resolution.md | 6 ++++-- .changesets/helm_host_configuration.md | 5 ++--- .changesets/maint_bnjjj_feat_854.md | 2 +- .../maint_bnjjj_fix_supergraph_events_span.md | 4 ++-- ...geal_query_planner_cache_key_improvements.md | 2 +- 20 files changed, 60 insertions(+), 58 deletions(-) diff --git a/.changesets/docs_clarify_authorization_directive_composition.md b/.changesets/docs_clarify_authorization_directive_composition.md index 52d0610cc9..5413e0234e 100644 --- a/.changesets/docs_clarify_authorization_directive_composition.md +++ b/.changesets/docs_clarify_authorization_directive_composition.md @@ -1,5 +1,6 @@ -### docs: correct authorization directive composition ([PR #6216](https://github.com/apollographql/router/pull/6216)) +### Clarify docs for authorization directive composition ([PR #6216](https://github.com/apollographql/router/pull/6216)) + +The docs for [authorization directive composition](https://www.apollographql.com/docs/graphos/routing/security/authorization#composition-and-federation) have been clarified, including corrected code examples. -Make authorization directive composition clearer and correct code examples By [@Meschreiber](https://github.com/Meschreiber) in https://github.com/apollographql/router/pull/6216 diff --git a/.changesets/feat_add_dns_resolution_strategy.md b/.changesets/feat_add_dns_resolution_strategy.md index cfaa9aaf74..399865ced1 100644 --- a/.changesets/feat_add_dns_resolution_strategy.md +++ b/.changesets/feat_add_dns_resolution_strategy.md @@ -1,6 +1,6 @@ -### Add ability to configure DNS resolution strategy ([PR #6109](https://github.com/apollographql/router/pull/6109)) +### Support DNS resolution strategy configuration ([PR #6109](https://github.com/apollographql/router/pull/6109)) -The router now supports choosing a DNS resolution strategy for the coprocessor's and subgraph's URLs. +The router now supports a configurable DNS resolution strategy for the URLs of coprocessors and subgraphs. The new option is called `dns_resolution_strategy` and supports the following values: * `ipv4_only` - Only query for `A` (IPv4) records. * `ipv6_only` - Only query for `AAAA` (IPv6) records. @@ -8,7 +8,8 @@ The new option is called `dns_resolution_strategy` and supports the following va * `ipv6_then_ipv4` - Query for `AAAA` (IPv6) records first; if that fails, query for `A` (IPv4) records. * `ipv4_then_ipv6`(default) - Query for `A` (IPv4) records first; if that fails, query for `AAAA` (IPv6) records. -To change the DNS resolution strategy applied to the subgraph's URL: +You can change the DNS resolution strategy applied to a subgraph's URL: + ```yaml title="router.yaml" traffic_shaping: all: @@ -16,7 +17,8 @@ traffic_shaping: ``` -You can also change the DNS resolution strategy applied to the coprocessor's URL: +You can also change the DNS resolution strategy applied to a coprocessor's URL: + ```yaml title="router.yaml" coprocessor: url: http://coprocessor.example.com:8081 diff --git a/.changesets/feat_error_extensions_service.md b/.changesets/feat_error_extensions_service.md index f182e44ea8..e8a1e09031 100644 --- a/.changesets/feat_error_extensions_service.md +++ b/.changesets/feat_error_extensions_service.md @@ -1,15 +1,18 @@ ### Add `extensions.service` for all subgraph errors ([PR #6191](https://github.com/apollographql/router/pull/6191)) + +For improved debuggability, the router now supports adding a subgraph's name as an extension to all errors originating from the subgraph. + If `include_subgraph_errors` is `true` for a particular subgraph, all errors originating in this subgraph will have the subgraph's name exposed as a `service` extension. -For example, if subgraph errors are enabled, like so: +You can enable subgraph errors with the following configuration: ```yaml title="router.yaml" include_subgraph_errors: all: true # Propagate errors from all subgraphs ``` -Note: This option is enabled by default in the [dev mode](./configuration/overview#dev-mode-defaults). +> Note: This option is enabled by default by the router's [dev mode](https://www.apollographql.com/docs/graphos/reference/router/configuration#dev-mode-defaults). -And this `products` subgraph returns an error, it will have a `service` extension: +Consequently, when a subgraph returns an error, it will have a `service` extension with the subgraph name as its value. The following example shows the extension for a `products` subgraph: ```json { diff --git a/.changesets/feat_geal_subgraph_request_id.md b/.changesets/feat_geal_subgraph_request_id.md index b5e0934132..07d85f8efd 100644 --- a/.changesets/feat_geal_subgraph_request_id.md +++ b/.changesets/feat_geal_subgraph_request_id.md @@ -1,5 +1,6 @@ -### Add a subgraph request id ([PR #5858](https://github.com/apollographql/router/pull/5858)) +### Add subgraph request id ([PR #5858](https://github.com/apollographql/router/pull/5858)) + +The router now supports a subgraph request ID that is a unique string identifying a subgraph request and response. It allows plugins and coprocessors to keep some state per subgraph request by matching on this ID. It's available in coprocessors as `subgraphRequestId` and Rhai scripts as `request.subgraph.id` and `response.subgraph.id`. -This is a unique string identifying a subgraph request and response, allowing plugins and coprocessors to keep some state per subgraph request by matching on this id. It is available in coprocessors as `subgraphRequestId` and rhai scripts as `request.subgraph.id` and `response.subgraph.id`. By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/5858 \ No newline at end of file diff --git a/.changesets/feat_lrlna_enable_generate_query_fragments_by_default.md b/.changesets/feat_lrlna_enable_generate_query_fragments_by_default.md index 2ae65008fd..d541706cd9 100644 --- a/.changesets/feat_lrlna_enable_generate_query_fragments_by_default.md +++ b/.changesets/feat_lrlna_enable_generate_query_fragments_by_default.md @@ -1,21 +1,14 @@ -### Compress subgraph operations by generating fragments +### Compress subgraph operations by generating fragments ([PR #6013](https://github.com/apollographql/router/pull/6013)) The router now compresses operations sent to subgraphs by default by generating fragment definitions and using them in the operation. -Initially, the router is using a very simple transformation that is implemented in both -the JavaScript and Native query planners. We will improve the algorithm after the JavaScript -planner is no longer supported. +This change enables `generate_query_fragments` by default while disabling `experimental_reuse_query_fragments`. When enabled, `experimental_reuse_query_fragments` attempts to intelligently reuse the fragment definitions +from the original operation. However, fragment generation with `generate_query_fragments` is much faster also produces better outputs in most cases. -This replaces a previous experimental algorithm that was enabled by default. -`experimental_reuse_query_fragments` attempted to intelligently reuse the fragment definitions -from the original operation. Fragment generation is much faster, and in most cases produces -better outputs too. +If you are relying on the shape of fragments in your subgraph operations or tests, you can opt out of the new algorithm with the configuration below. -If you are relying on the shape of fragments in your subgraph operations or tests, you can opt -out of the new algorithm with the configuration below. Note we strongly recommend against -relying on the shape of planned operations as new router features and optimizations may affect -it, and we intend to remove `experimental_reuse_query_fragments` in a future release. +> Note: The subgraph operations generated by the query planner are not guaranteed consistent release over release. We strongly recommend against relying on the shape of planned subgraph operations, as new router features and optimizations will continuously affect it. We plan to remove `experimental_reuse_query_fragments` in a future release. ```yaml supergraph: diff --git a/.changesets/feat_max_headers.md b/.changesets/feat_max_headers.md index 30939d802a..97c58995a7 100644 --- a/.changesets/feat_max_headers.md +++ b/.changesets/feat_max_headers.md @@ -1,15 +1,15 @@ -### Configuration Options for HTTP/1 Max Headers and Buffer Limits ([PR #6194](https://github.com/apollographql/router/pull/6194)) +### Configuration options for HTTP/1 max headers and buffer limits ([PR #6194](https://github.com/apollographql/router/pull/6194)) This update introduces configuration options that allow you to adjust the maximum number of HTTP/1 request headers and the maximum buffer size allocated for headers. -By default, the Router accepts HTTP/1 requests with up to 100 headers and allocates ~400kib of buffer space to store them. If you need to handle requests with more headers or require a different buffer size, you can now configure these limits in the Router's configuration file: +By default, the router accepts HTTP/1 requests with up to 100 headers and allocates ~400 KiB of buffer space to store them. If you need to handle requests with more headers or require a different buffer size, you can now configure these limits in the router's configuration file: ```yaml limits: http1_request_max_headers: 200 http1_request_max_buf_size: 200kib ``` -Note for Rust Crate Users: If you are using the Router as a Rust crate, the `http1_request_max_buf_size` option requires the `hyper_header_limits` feature and also necessitates using Apollo's fork of the Hyper crate until the [changes are merged upstream](https://github.com/hyperium/hyper/pull/3523). +If you are using the router as a Rust crate, the `http1_request_max_buf_size` option requires the `hyper_header_limits` feature and also necessitates using Apollo's fork of the Hyper crate until the [changes are merged upstream](https://github.com/hyperium/hyper/pull/3523). You can include this fork by adding the following patch to your Cargo.toml file: ```toml [patch.crates-io] diff --git a/.changesets/feat_router_528_impl_set_context.md b/.changesets/feat_router_528_impl_set_context.md index f47bb8ac23..b805deca59 100644 --- a/.changesets/feat_router_528_impl_set_context.md +++ b/.changesets/feat_router_528_impl_set_context.md @@ -1,4 +1,4 @@ -### Add `@context` support in the Native Query Planner ([PR #6310](https://github.com/apollographql/router/pull/6310)) +### Add `@context` support in the native query planner ([PR #6310](https://github.com/apollographql/router/pull/6310)) The [`@context`](https://www.apollographql.com/docs/graphos/reference/federation/directives#context) feature is now available in the native query planner. This brings the native query planner to feature parity with the legacy query planner for all Federation v2 graphs. diff --git a/.changesets/fix_bryn_fix_header_propagation.md b/.changesets/fix_bryn_fix_header_propagation.md index 2dabfdbe00..fe402a26c6 100644 --- a/.changesets/fix_bryn_fix_header_propagation.md +++ b/.changesets/fix_bryn_fix_header_propagation.md @@ -1,6 +1,6 @@ -### Fix header propagation where renames have already taken place ([PR #6281](https://github.com/apollographql/router/pull/6281)) +### Renamed headers' original values can again be propagated ([PR #6281](https://github.com/apollographql/router/pull/6281)) -https://github.com/apollographql/router/pull/4535 introduced a regression where the following header propagation config would not work: +[PR #4535](https://github.com/apollographql/router/pull/4535) introduced a regression where the following header propagation config would not work: ```yaml headers: @@ -12,7 +12,7 @@ headers: rename: c ``` -The goal of the original PR was to prevent multiple headers from being mapped to a single target header. However, it did not consider renames, and instead prevented multiple mappings from the same source header. -The Router will now propagate headers properly ensuring that a target header is only propagated to once. +The goal of the original PR was to prevent multiple headers from being mapped to a single target header. However, it did not consider renames and instead prevented multiple mappings from the same source header. +The router now propagates headers properly and ensures that a target header is only propagated to once. By [@BrynCooke](https://github.com/BrynCooke) in https://github.com/apollographql/router/pull/6281 diff --git a/.changesets/fix_fix_file_upload_variable_placeholder.md b/.changesets/fix_fix_file_upload_variable_placeholder.md index e656525589..2e7dc5a521 100644 --- a/.changesets/fix_fix_file_upload_variable_placeholder.md +++ b/.changesets/fix_fix_file_upload_variable_placeholder.md @@ -1,7 +1,7 @@ -### File Uploads: Remove Placeholders from Query Variables ([PR #6293](https://github.com/apollographql/router/pull/6293)) +### Remove placeholders from file upload query variables ([PR #6293](https://github.com/apollographql/router/pull/6293)) -Fixed an issue where file upload query variables in subgraph requests contained internal placeholders. +Previously, file upload query variables in subgraph requests incorrectly contained internal placeholders. According to the [GraphQL Multipart Request Spec](https://github.com/jaydenseric/graphql-multipart-request-spec?tab=readme-ov-file#multipart-form-field-structure), these variables should be set to null. -This fix ensures that the Router complies with the specification and improves compatibility with subgraphs handling file uploads. +This issue has been fixed by ensuring that the router complies with the specification and improving compatibility with subgraphs handling file uploads. By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6293 diff --git a/.changesets/fix_garypen_log_less_error_for_subgraph_batching.md b/.changesets/fix_garypen_log_less_error_for_subgraph_batching.md index f81796d01a..9f7d8d1628 100644 --- a/.changesets/fix_garypen_log_less_error_for_subgraph_batching.md +++ b/.changesets/fix_garypen_log_less_error_for_subgraph_batching.md @@ -1,7 +1,5 @@ -### If subgraph batching, do not log response data for notification failure ([PR #6150](https://github.com/apollographql/router/pull/6150)) +### Don't log response data upon notification failure for subgraph batching ([PR #6150](https://github.com/apollographql/router/pull/6150)) -A subgraph response may contain a lot of data and/or PII data. - -For a subgraph batching operation, we should not log out the entire subgraph response when failing to notify a waiting batch participant. +For a subgraph batching operation, the router now doesn't log the entire subgraph response when failing to notify a waiting batch participant. This saves the router from logging the large amount of data (PII and/or non-PII data) that a subgraph response may contain. By [@garypen](https://github.com/garypen) in https://github.com/apollographql/router/pull/6150 \ No newline at end of file diff --git a/.changesets/fix_geal_deduplication_processing_time.md b/.changesets/fix_geal_deduplication_processing_time.md index a3a75c467e..71e10b87ed 100644 --- a/.changesets/fix_geal_deduplication_processing_time.md +++ b/.changesets/fix_geal_deduplication_processing_time.md @@ -1,5 +1,5 @@ -### do not count the wait time in deduplication as processing time ([PR #6207](https://github.com/apollographql/router/pull/6207)) +### Overhead processing metrics should exclude subgraph response time when deduplication is enabled ([PR #6207](https://github.com/apollographql/router/pull/6207)) -waiting for a deduplicated request was incorrectly counted as time spent in the router overhead, while most of it was actually spent waiting for the subgraph response. +The router's calculated overhead processing time has been fixed, where the time spent waiting for the subgraph response of a deduplicated request had been incorrectly included. By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/6207 \ No newline at end of file diff --git a/.changesets/fix_geal_introspection_dedup_fix.md b/.changesets/fix_geal_introspection_dedup_fix.md index f93112b815..3fc10a3748 100644 --- a/.changesets/fix_geal_introspection_dedup_fix.md +++ b/.changesets/fix_geal_introspection_dedup_fix.md @@ -1,5 +1,5 @@ -### Fix introspection query deduplication ([Issue #6249](https://github.com/apollographql/router/issues/6249)) +### Introspection response deduplication should always produce results ([Issue #6249](https://github.com/apollographql/router/issues/6249)) -To reduce CPU usage, query planning and introspection queries are deduplicated. In some cases, deduplicated introspection queries were not receiving their result. This makes sure that answers are sent in all cases. +To reduce CPU usage, query planning and introspection queries are deduplicated. In some cases, deduplicated introspection queries were not receiving their result. This issue has been fixed, and the router now sends results in all cases. By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/6257 \ No newline at end of file diff --git a/.changesets/fix_renee_limit_errors.md b/.changesets/fix_renee_limit_errors.md index 60a3404ccc..c2df146205 100644 --- a/.changesets/fix_renee_limit_errors.md +++ b/.changesets/fix_renee_limit_errors.md @@ -1,6 +1,5 @@ -### Limit the amount of GraphQL validation errors returned in the response ([PR #6187](https://github.com/apollographql/router/pull/6187)) +### Limit the amount of GraphQL validation errors returned per response ([PR #6187](https://github.com/apollographql/router/pull/6187)) -When an invalid query is submitted, the router now returns at most 100 GraphQL parsing and validation errors in the response. -This prevents generating a very large response for nonsense documents. +When an invalid query is submitted, the router now returns at most one hundred GraphQL parsing and validation errors in a response. This prevents generating too large of a response for a nonsensical document. By [@goto-bus-stop](https://github.com/goto-bus-stop) in https://github.com/apollographql/router/pull/6187 \ No newline at end of file diff --git a/.changesets/fix_simon_compute_jobs.md b/.changesets/fix_simon_compute_jobs.md index 604f1624c5..c7ad4c9c38 100644 --- a/.changesets/fix_simon_compute_jobs.md +++ b/.changesets/fix_simon_compute_jobs.md @@ -1,6 +1,8 @@ -### Move heavy computation to a thread pool with a priority queue +### Move heavy computation to a thread pool with a priority queue ([PR #6247](https://github.com/apollographql/router/pull/6247)) -These components can take non-trivial amounts of CPU time: +The router now avoids blocking threads when executing asynchronous code by using a thread pool with a priority queue. + +This improves the performance of the following components can take non-trivial amounts of CPU time: * GraphQL parsing * GraphQL validation diff --git a/.changesets/fix_tninesling_demand_control_variable_scoring.md b/.changesets/fix_tninesling_demand_control_variable_scoring.md index 6ec6b35e22..fdac861553 100644 --- a/.changesets/fix_tninesling_demand_control_variable_scoring.md +++ b/.changesets/fix_tninesling_demand_control_variable_scoring.md @@ -1,6 +1,6 @@ ### Fix demand control panic for custom scalars that represent non-GraphQL-compliant JSON ([PR #6288](https://github.com/apollographql/router/pull/6288)) -This panic could be triggered with the following schema: +Previously, a panic could be triggered in the router's demand control plugin with the following schema: ``` scalar ArbitraryJson @@ -34,6 +34,8 @@ and variables } ``` -During scoring, the demand control plugin would attempt to convert the variable structure into a GraphQL-compliant structure requiring valid GraphQL names as keys, but the dot characters in the keys would cause a panic. With this fix, only the GraphQL compliant part of the input object is scored, and the arbitrary JSON marked by the custom scalar is scored as an opaque scalar, similar to how we process built-ins like `Int` or `String`. +During scoring, the demand control plugin would attempt to convert the variable structure into a GraphQL-compliant structure requiring valid GraphQL names as keys. The dot characters in the keys however would cause a panic. + +With this fix, only the GraphQL compliant part of the input object is scored, and the arbitrary JSON marked by the custom scalar is scored as an opaque scalar (similar to how built-ins like `Int` or `String` are processed). By [@tninesling](https://github.com/tninesling) in https://github.com/apollographql/router/pull/6288 diff --git a/.changesets/fix_tninesling_typename_resolution.md b/.changesets/fix_tninesling_typename_resolution.md index 934d4ed5d2..890cb13ff6 100644 --- a/.changesets/fix_tninesling_typename_resolution.md +++ b/.changesets/fix_tninesling_typename_resolution.md @@ -1,5 +1,7 @@ -### Do not override concrete type names with interface names when merging responses ([PR #6250](https://github.com/apollographql/router/pull/6250)) +### Fix incorrect overriding of concrete type names with interface names when merging responses ([PR #6250](https://github.com/apollographql/router/pull/6250)) -When using `@interfaceObject`, differing pieces of data can come back with either concrete types or interface types depending on the source. To make the response merging order-agnostic, check the schema to ensure concrete types are not overwritten with interfaces or less specific types. +When using `@interfaceObject`, differing pieces of data can come back with either concrete types or interface types depending on the source. Previously, receiving the data in a particular order could incorrectly result in the interface name of a type overwriting its concrete name. + +To make the response merging order-agnostic, the router now checks the schema to ensure concrete types are not overwritten with interfaces or less specific types. By [@tninesling](https://github.com/tninesling) in https://github.com/apollographql/router/pull/6250 diff --git a/.changesets/helm_host_configuration.md b/.changesets/helm_host_configuration.md index f64334803d..e26bdc6dd1 100644 --- a/.changesets/helm_host_configuration.md +++ b/.changesets/helm_host_configuration.md @@ -1,6 +1,5 @@ -### Allow for configuration of the host via the helm template for virtual service ([PR #5545](https://github.com/apollographql/router/pull/5795)) +### Allow configuring host via Helm template for virtual service ([PR #5545](https://github.com/apollographql/router/pull/5795)) -Using the virtual service template change allows the configuration of the host from a variable when doing helm deploy. -The default of any host causes issues for those that use different hosts for a single AKS cluster +When deploying via Helm, you can now configure hosts in `virtualservice.yaml` as a single host or a range of hosts. This is helpful when different hosts could be used within a cluster. By [@nicksephora](https://github.com/nicksephora) in https://github.com/apollographql/router/pull/5545 diff --git a/.changesets/maint_bnjjj_feat_854.md b/.changesets/maint_bnjjj_feat_854.md index b06904f7bd..2f5f7a762f 100644 --- a/.changesets/maint_bnjjj_feat_854.md +++ b/.changesets/maint_bnjjj_feat_854.md @@ -1,5 +1,5 @@ ### Add entity caching invalidation configuration metrics ([PR #6286](https://github.com/apollographql/router/pull/6286)) -Add metrics for our analytics to know if invalidation is enabled. +We've added metrics for our analytics to know if entity caching invalidation is enabled. By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/6286 \ No newline at end of file diff --git a/.changesets/maint_bnjjj_fix_supergraph_events_span.md b/.changesets/maint_bnjjj_fix_supergraph_events_span.md index 00f5cf241d..a0548cb374 100644 --- a/.changesets/maint_bnjjj_fix_supergraph_events_span.md +++ b/.changesets/maint_bnjjj_fix_supergraph_events_span.md @@ -1,5 +1,5 @@ -### Don't create a stub span for supergraph events if it already has a current span ([PR #6096](https://github.com/apollographql/router/pull/6096)) +### Avoid creating stub span for supergraph events if current span exists ([PR #6096](https://github.com/apollographql/router/pull/6096)) -Don't create useless span when we already have a span available to use the span's extensions. +The router optimized its telemetry implementation by not creating a redundant span when it already has a span available to use the span's extensions for supergraph events. By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/6096 \ No newline at end of file diff --git a/.changesets/maint_geal_query_planner_cache_key_improvements.md b/.changesets/maint_geal_query_planner_cache_key_improvements.md index 720836429f..afb446115a 100644 --- a/.changesets/maint_geal_query_planner_cache_key_improvements.md +++ b/.changesets/maint_geal_query_planner_cache_key_improvements.md @@ -3,6 +3,6 @@ > [!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. -This brings several performance improvements to the query plan cache key generation. In particular, it changes the distributed cache's key format, adding prefixes to the different key segments, to help in debugging. +Several performance improvements have been implemented for query plan cache key generation. In particular, the distributed cache's key format has changed, which adds prefixes to the different key segments to help in debugging. By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/6206 \ No newline at end of file From 5915e21d7f2d87a4a9f8c1ceedd474c652861771 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Mon, 25 Nov 2024 14:11:47 +0100 Subject: [PATCH 64/77] Update .changesets/fix_simon_compute_jobs.md Co-authored-by: Edward Huang --- .changesets/fix_simon_compute_jobs.md | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/.changesets/fix_simon_compute_jobs.md b/.changesets/fix_simon_compute_jobs.md index c7ad4c9c38..ac7f1fccaa 100644 --- a/.changesets/fix_simon_compute_jobs.md +++ b/.changesets/fix_simon_compute_jobs.md @@ -10,17 +10,12 @@ This improves the performance of the following components can take non-trivial a * Schema introspection In order to avoid blocking threads that execute asynchronous code, -they are now run (in their respective Rust implementations) -in a new thread pool whose size is based on available CPU cores, -with a priority queue. -Previously we used Tokioโ€™s [`spawn_blocking`] for this purpose, -but it is appears to be intended for blocking I/O -and uses up to 512 threads so it isnโ€™t a great fit for computation tasks. - -`apollo.router.compute_jobs.queued` is a new gauge metric for the number of items in this new queue. -When the new query planner is enabled, the dedicated queue is no longer used -and the `apollo.router.query_planning.queued` metric is no longer emitted. - -[`spawn_blocking`]: https://docs.rs/tokio/latest/tokio/task/fn.spawn_blocking.html +they are now run in a new thread pool with a priority queue. The size of the thread pool is based on the number of available CPU cores. + +The thread pool replaces the router's prior implementation that used Tokioโ€™s [`spawn_blocking`](https://docs.rs/tokio/latest/tokio/task/fn.spawn_blocking.html). + +`apollo.router.compute_jobs.queued` is a new gauge metric for the number of items in the thread pool's priority queue. + +> Note: when the native query planner is enabled, the dedicated queue of the legacy query planner is no longer used, so the `apollo.router.query_planning.queued` metric is no longer emitted. By [@SimonSapin](https://github.com/SimonSapin) in https://github.com/apollographql/router/pull/6247 From b98a9011d7df7e456adaa9a07f6f0c0bfbe065fb Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 26 Nov 2024 15:43:40 +0100 Subject: [PATCH 65/77] Allow compute jobs to use all available CPUs (#6335) With the previous thread pool size we saw benchmark regressions in 1.58.0-rc compared to 1.57.0 --- apollo-router/src/compute_job.rs | 38 +++++--------------------------- 1 file changed, 5 insertions(+), 33 deletions(-) diff --git a/apollo-router/src/compute_job.rs b/apollo-router/src/compute_job.rs index 7672dfea83..64fe16b20d 100644 --- a/apollo-router/src/compute_job.rs +++ b/apollo-router/src/compute_job.rs @@ -14,31 +14,13 @@ use crate::metrics::meter_provider; /// reaches `QUEUE_SOFT_CAPACITY_PER_THREAD * thread_pool_size()` const QUEUE_SOFT_CAPACITY_PER_THREAD: usize = 20; -/// Leave a fraction of CPU cores free to run Tokio threads even if this thread pool is very busy: -/// -/// available: 1 pool size: 1 -/// available: 2 pool size: 1 -/// available: 3 pool size: 2 -/// available: 4 pool size: 3 -/// available: 5 pool size: 4 -/// ... -/// available: 8 pool size: 7 -/// available: 9 pool size: 7 -/// ... -/// available: 16 pool size: 14 -/// available: 17 pool size: 14 -/// ... -/// available: 32 pool size: 28 +/// Let this thread pool use all available resources if it can. +/// In the worst case, weโ€™ll have moderate context switching cost +/// as the kernelโ€™s scheduler distributes time to it or Tokio or other threads. fn thread_pool_size() -> usize { - let available = std::thread::available_parallelism() + std::thread::available_parallelism() .expect("available_parallelism() failed") - .get(); - thread_poll_size_for_available_parallelism(available) -} - -fn thread_poll_size_for_available_parallelism(available: usize) -> usize { - let reserved = available.div_ceil(8); - (available - reserved).max(1) + .get() } type Job = Box; @@ -135,14 +117,4 @@ mod tests { // Evidence of fearless parallel sleep: assert!(start.elapsed() < Duration::from_millis(1_400)); } - - #[test] - fn pool_size() { - assert_eq!(thread_poll_size_for_available_parallelism(1), 1); - assert_eq!(thread_poll_size_for_available_parallelism(2), 1); - assert_eq!(thread_poll_size_for_available_parallelism(3), 2); - assert_eq!(thread_poll_size_for_available_parallelism(4), 3); - assert_eq!(thread_poll_size_for_available_parallelism(31), 27); - assert_eq!(thread_poll_size_for_available_parallelism(32), 28); - } } From eeb63ec988bdd8936b3af38ddd3ad19c5a94f05d Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Tue, 26 Nov 2024 16:44:40 +0200 Subject: [PATCH 66/77] prep release: v1.58.0 (#6331) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Renรฉe Co-authored-by: Iryna Shestak --- ...ify_authorization_directive_composition.md | 6 - .../feat_add_dns_resolution_strategy.md | 30 -- .changesets/feat_error_extensions_service.md | 32 -- .changesets/feat_geal_subgraph_request_id.md | 6 - ...ble_generate_query_fragments_by_default.md | 19 - .changesets/feat_max_headers.md | 19 - .../feat_router_528_impl_set_context.md | 6 - .../fix_bryn_fix_header_propagation.md | 18 - ...ix_fix_file_upload_variable_placeholder.md | 7 - ...en_log_less_error_for_subgraph_batching.md | 5 - .../fix_geal_deduplication_processing_time.md | 5 - .../fix_geal_introspection_dedup_fix.md | 5 - .changesets/fix_renee_limit_errors.md | 5 - .changesets/fix_simon_compute_jobs.md | 21 - ...nesling_demand_control_variable_scoring.md | 41 -- ...inesling_remove_demand_control_warnings.md | 5 - .../fix_tninesling_typename_resolution.md | 7 - .changesets/maint_bnjjj_feat_854.md | 5 - .../maint_bnjjj_fix_supergraph_events_span.md | 5 - ...al_query_planner_cache_key_improvements.md | 8 - CHANGELOG.md | 290 +++++++++++ Cargo.lock | 8 +- apollo-federation/Cargo.toml | 2 +- apollo-router-benchmarks/Cargo.toml | 2 +- apollo-router-scaffold/Cargo.toml | 2 +- .../templates/base/Cargo.template.toml | 2 +- .../templates/base/xtask/Cargo.template.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 | 6 +- licenses.html | 457 ++---------------- scripts/install.sh | 2 +- 35 files changed, 352 insertions(+), 690 deletions(-) delete mode 100644 .changesets/docs_clarify_authorization_directive_composition.md delete mode 100644 .changesets/feat_add_dns_resolution_strategy.md delete mode 100644 .changesets/feat_error_extensions_service.md delete mode 100644 .changesets/feat_geal_subgraph_request_id.md delete mode 100644 .changesets/feat_lrlna_enable_generate_query_fragments_by_default.md delete mode 100644 .changesets/feat_max_headers.md delete mode 100644 .changesets/feat_router_528_impl_set_context.md delete mode 100644 .changesets/fix_bryn_fix_header_propagation.md delete mode 100644 .changesets/fix_fix_file_upload_variable_placeholder.md delete mode 100644 .changesets/fix_garypen_log_less_error_for_subgraph_batching.md delete mode 100644 .changesets/fix_geal_deduplication_processing_time.md delete mode 100644 .changesets/fix_geal_introspection_dedup_fix.md delete mode 100644 .changesets/fix_renee_limit_errors.md delete mode 100644 .changesets/fix_simon_compute_jobs.md delete mode 100644 .changesets/fix_tninesling_demand_control_variable_scoring.md delete mode 100644 .changesets/fix_tninesling_remove_demand_control_warnings.md delete mode 100644 .changesets/fix_tninesling_typename_resolution.md delete mode 100644 .changesets/maint_bnjjj_feat_854.md delete mode 100644 .changesets/maint_bnjjj_fix_supergraph_events_span.md delete mode 100644 .changesets/maint_geal_query_planner_cache_key_improvements.md diff --git a/.changesets/docs_clarify_authorization_directive_composition.md b/.changesets/docs_clarify_authorization_directive_composition.md deleted file mode 100644 index 5413e0234e..0000000000 --- a/.changesets/docs_clarify_authorization_directive_composition.md +++ /dev/null @@ -1,6 +0,0 @@ -### Clarify docs for authorization directive composition ([PR #6216](https://github.com/apollographql/router/pull/6216)) - -The docs for [authorization directive composition](https://www.apollographql.com/docs/graphos/routing/security/authorization#composition-and-federation) have been clarified, including corrected code examples. - - -By [@Meschreiber](https://github.com/Meschreiber) in https://github.com/apollographql/router/pull/6216 diff --git a/.changesets/feat_add_dns_resolution_strategy.md b/.changesets/feat_add_dns_resolution_strategy.md deleted file mode 100644 index 399865ced1..0000000000 --- a/.changesets/feat_add_dns_resolution_strategy.md +++ /dev/null @@ -1,30 +0,0 @@ -### Support DNS resolution strategy configuration ([PR #6109](https://github.com/apollographql/router/pull/6109)) - -The router now supports a configurable DNS resolution strategy for the URLs of coprocessors and subgraphs. -The new option is called `dns_resolution_strategy` and supports the following values: -* `ipv4_only` - Only query for `A` (IPv4) records. -* `ipv6_only` - Only query for `AAAA` (IPv6) records. -* `ipv4_and_ipv6` - Query for both `A` (IPv4) and `AAAA` (IPv6) records in parallel. -* `ipv6_then_ipv4` - Query for `AAAA` (IPv6) records first; if that fails, query for `A` (IPv4) records. -* `ipv4_then_ipv6`(default) - Query for `A` (IPv4) records first; if that fails, query for `AAAA` (IPv6) records. - -You can change the DNS resolution strategy applied to a subgraph's URL: - -```yaml title="router.yaml" -traffic_shaping: - all: - dns_resolution_strategy: ipv4_then_ipv6 - -``` - -You can also change the DNS resolution strategy applied to a coprocessor's URL: - -```yaml title="router.yaml" -coprocessor: - url: http://coprocessor.example.com:8081 - client: - dns_resolution_strategy: ipv4_then_ipv6 - -``` - -By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6109 diff --git a/.changesets/feat_error_extensions_service.md b/.changesets/feat_error_extensions_service.md deleted file mode 100644 index e8a1e09031..0000000000 --- a/.changesets/feat_error_extensions_service.md +++ /dev/null @@ -1,32 +0,0 @@ -### Add `extensions.service` for all subgraph errors ([PR #6191](https://github.com/apollographql/router/pull/6191)) - - -For improved debuggability, the router now supports adding a subgraph's name as an extension to all errors originating from the subgraph. - -If `include_subgraph_errors` is `true` for a particular subgraph, all errors originating in this subgraph will have the subgraph's name exposed as a `service` extension. - -You can enable subgraph errors with the following configuration: -```yaml title="router.yaml" -include_subgraph_errors: - all: true # Propagate errors from all subgraphs -``` -> Note: This option is enabled by default by the router's [dev mode](https://www.apollographql.com/docs/graphos/reference/router/configuration#dev-mode-defaults). - -Consequently, when a subgraph returns an error, it will have a `service` extension with the subgraph name as its value. The following example shows the extension for a `products` subgraph: - -```json -{ - "data": null, - "errors": [ - { - "message": "Invalid product ID", - "path": [], - "extensions": { - "service": "products" - } - } - ] -} -``` - -By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6191 \ No newline at end of file diff --git a/.changesets/feat_geal_subgraph_request_id.md b/.changesets/feat_geal_subgraph_request_id.md deleted file mode 100644 index 07d85f8efd..0000000000 --- a/.changesets/feat_geal_subgraph_request_id.md +++ /dev/null @@ -1,6 +0,0 @@ -### Add subgraph request id ([PR #5858](https://github.com/apollographql/router/pull/5858)) - -The router now supports a subgraph request ID that is a unique string identifying a subgraph request and response. It allows plugins and coprocessors to keep some state per subgraph request by matching on this ID. It's available in coprocessors as `subgraphRequestId` and Rhai scripts as `request.subgraph.id` and `response.subgraph.id`. - - -By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/5858 \ No newline at end of file diff --git a/.changesets/feat_lrlna_enable_generate_query_fragments_by_default.md b/.changesets/feat_lrlna_enable_generate_query_fragments_by_default.md deleted file mode 100644 index d541706cd9..0000000000 --- a/.changesets/feat_lrlna_enable_generate_query_fragments_by_default.md +++ /dev/null @@ -1,19 +0,0 @@ -### Compress subgraph operations by generating fragments ([PR #6013](https://github.com/apollographql/router/pull/6013)) - -The router now compresses operations sent to subgraphs by default by generating fragment -definitions and using them in the operation. - -This change enables `generate_query_fragments` by default while disabling `experimental_reuse_query_fragments`. When enabled, `experimental_reuse_query_fragments` attempts to intelligently reuse the fragment definitions -from the original operation. However, fragment generation with `generate_query_fragments` is much faster also produces better outputs in most cases. - -If you are relying on the shape of fragments in your subgraph operations or tests, you can opt out of the new algorithm with the configuration below. - -> Note: The subgraph operations generated by the query planner are not guaranteed consistent release over release. We strongly recommend against relying on the shape of planned subgraph operations, as new router features and optimizations will continuously affect it. We plan to remove `experimental_reuse_query_fragments` in a future release. - -```yaml -supergraph: - generate_query_fragments: false - experimental_reuse_query_fragments: true -``` - -By [@lrlna](https://github.com/lrlna) in https://github.com/apollographql/router/pull/6013 diff --git a/.changesets/feat_max_headers.md b/.changesets/feat_max_headers.md deleted file mode 100644 index 97c58995a7..0000000000 --- a/.changesets/feat_max_headers.md +++ /dev/null @@ -1,19 +0,0 @@ -### Configuration options for HTTP/1 max headers and buffer limits ([PR #6194](https://github.com/apollographql/router/pull/6194)) - -This update introduces configuration options that allow you to adjust the maximum number of HTTP/1 request headers and the maximum buffer size allocated for headers. - -By default, the router accepts HTTP/1 requests with up to 100 headers and allocates ~400 KiB of buffer space to store them. If you need to handle requests with more headers or require a different buffer size, you can now configure these limits in the router's configuration file: -```yaml -limits: - http1_request_max_headers: 200 - http1_request_max_buf_size: 200kib -``` - -If you are using the router as a Rust crate, the `http1_request_max_buf_size` option requires the `hyper_header_limits` feature and also necessitates using Apollo's fork of the Hyper crate until the [changes are merged upstream](https://github.com/hyperium/hyper/pull/3523). -You can include this fork by adding the following patch to your Cargo.toml file: -```toml -[patch.crates-io] -"hyper" = { git = "https://github.com/apollographql/hyper.git", tag = "header-customizations-20241108" } -``` - -By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6194 diff --git a/.changesets/feat_router_528_impl_set_context.md b/.changesets/feat_router_528_impl_set_context.md deleted file mode 100644 index b805deca59..0000000000 --- a/.changesets/feat_router_528_impl_set_context.md +++ /dev/null @@ -1,6 +0,0 @@ -### Add `@context` support in the native query planner ([PR #6310](https://github.com/apollographql/router/pull/6310)) - -The [`@context`](https://www.apollographql.com/docs/graphos/reference/federation/directives#context) feature is now available in the native query planner. -This brings the native query planner to feature parity with the legacy query planner for all Federation v2 graphs. - -By [@clenfest](https://github.com/clenfest), [@TylerBloom](https://github.com/TylerBloom) in https://github.com/apollographql/router/pull/6310 \ No newline at end of file diff --git a/.changesets/fix_bryn_fix_header_propagation.md b/.changesets/fix_bryn_fix_header_propagation.md deleted file mode 100644 index fe402a26c6..0000000000 --- a/.changesets/fix_bryn_fix_header_propagation.md +++ /dev/null @@ -1,18 +0,0 @@ -### Renamed headers' original values can again be propagated ([PR #6281](https://github.com/apollographql/router/pull/6281)) - -[PR #4535](https://github.com/apollographql/router/pull/4535) introduced a regression where the following header propagation config would not work: - -```yaml -headers: -- propagate: - named: a - rename: b -- propagate: - named: a - rename: c -``` - -The goal of the original PR was to prevent multiple headers from being mapped to a single target header. However, it did not consider renames and instead prevented multiple mappings from the same source header. -The router now propagates headers properly and ensures that a target header is only propagated to once. - -By [@BrynCooke](https://github.com/BrynCooke) in https://github.com/apollographql/router/pull/6281 diff --git a/.changesets/fix_fix_file_upload_variable_placeholder.md b/.changesets/fix_fix_file_upload_variable_placeholder.md deleted file mode 100644 index 2e7dc5a521..0000000000 --- a/.changesets/fix_fix_file_upload_variable_placeholder.md +++ /dev/null @@ -1,7 +0,0 @@ -### Remove placeholders from file upload query variables ([PR #6293](https://github.com/apollographql/router/pull/6293)) - -Previously, file upload query variables in subgraph requests incorrectly contained internal placeholders. -According to the [GraphQL Multipart Request Spec](https://github.com/jaydenseric/graphql-multipart-request-spec?tab=readme-ov-file#multipart-form-field-structure), these variables should be set to null. -This issue has been fixed by ensuring that the router complies with the specification and improving compatibility with subgraphs handling file uploads. - -By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6293 diff --git a/.changesets/fix_garypen_log_less_error_for_subgraph_batching.md b/.changesets/fix_garypen_log_less_error_for_subgraph_batching.md deleted file mode 100644 index 9f7d8d1628..0000000000 --- a/.changesets/fix_garypen_log_less_error_for_subgraph_batching.md +++ /dev/null @@ -1,5 +0,0 @@ -### Don't log response data upon notification failure for subgraph batching ([PR #6150](https://github.com/apollographql/router/pull/6150)) - -For a subgraph batching operation, the router now doesn't log the entire subgraph response when failing to notify a waiting batch participant. This saves the router from logging the large amount of data (PII and/or non-PII data) that a subgraph response may contain. - -By [@garypen](https://github.com/garypen) in https://github.com/apollographql/router/pull/6150 \ No newline at end of file diff --git a/.changesets/fix_geal_deduplication_processing_time.md b/.changesets/fix_geal_deduplication_processing_time.md deleted file mode 100644 index 71e10b87ed..0000000000 --- a/.changesets/fix_geal_deduplication_processing_time.md +++ /dev/null @@ -1,5 +0,0 @@ -### Overhead processing metrics should exclude subgraph response time when deduplication is enabled ([PR #6207](https://github.com/apollographql/router/pull/6207)) - -The router's calculated overhead processing time has been fixed, where the time spent waiting for the subgraph response of a deduplicated request had been incorrectly included. - -By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/6207 \ No newline at end of file diff --git a/.changesets/fix_geal_introspection_dedup_fix.md b/.changesets/fix_geal_introspection_dedup_fix.md deleted file mode 100644 index 3fc10a3748..0000000000 --- a/.changesets/fix_geal_introspection_dedup_fix.md +++ /dev/null @@ -1,5 +0,0 @@ -### Introspection response deduplication should always produce results ([Issue #6249](https://github.com/apollographql/router/issues/6249)) - -To reduce CPU usage, query planning and introspection queries are deduplicated. In some cases, deduplicated introspection queries were not receiving their result. This issue has been fixed, and the router now sends results in all cases. - -By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/6257 \ No newline at end of file diff --git a/.changesets/fix_renee_limit_errors.md b/.changesets/fix_renee_limit_errors.md deleted file mode 100644 index c2df146205..0000000000 --- a/.changesets/fix_renee_limit_errors.md +++ /dev/null @@ -1,5 +0,0 @@ -### Limit the amount of GraphQL validation errors returned per response ([PR #6187](https://github.com/apollographql/router/pull/6187)) - -When an invalid query is submitted, the router now returns at most one hundred GraphQL parsing and validation errors in a response. This prevents generating too large of a response for a nonsensical document. - -By [@goto-bus-stop](https://github.com/goto-bus-stop) in https://github.com/apollographql/router/pull/6187 \ No newline at end of file diff --git a/.changesets/fix_simon_compute_jobs.md b/.changesets/fix_simon_compute_jobs.md deleted file mode 100644 index ac7f1fccaa..0000000000 --- a/.changesets/fix_simon_compute_jobs.md +++ /dev/null @@ -1,21 +0,0 @@ -### Move heavy computation to a thread pool with a priority queue ([PR #6247](https://github.com/apollographql/router/pull/6247)) - -The router now avoids blocking threads when executing asynchronous code by using a thread pool with a priority queue. - -This improves the performance of the following components can take non-trivial amounts of CPU time: - -* GraphQL parsing -* GraphQL validation -* Query planning -* Schema introspection - -In order to avoid blocking threads that execute asynchronous code, -they are now run in a new thread pool with a priority queue. The size of the thread pool is based on the number of available CPU cores. - -The thread pool replaces the router's prior implementation that used Tokioโ€™s [`spawn_blocking`](https://docs.rs/tokio/latest/tokio/task/fn.spawn_blocking.html). - -`apollo.router.compute_jobs.queued` is a new gauge metric for the number of items in the thread pool's priority queue. - -> Note: when the native query planner is enabled, the dedicated queue of the legacy query planner is no longer used, so the `apollo.router.query_planning.queued` metric is no longer emitted. - -By [@SimonSapin](https://github.com/SimonSapin) in https://github.com/apollographql/router/pull/6247 diff --git a/.changesets/fix_tninesling_demand_control_variable_scoring.md b/.changesets/fix_tninesling_demand_control_variable_scoring.md deleted file mode 100644 index fdac861553..0000000000 --- a/.changesets/fix_tninesling_demand_control_variable_scoring.md +++ /dev/null @@ -1,41 +0,0 @@ -### Fix demand control panic for custom scalars that represent non-GraphQL-compliant JSON ([PR #6288](https://github.com/apollographql/router/pull/6288)) - -Previously, a panic could be triggered in the router's demand control plugin with the following schema: - -``` -scalar ArbitraryJson - -type MyInput { - json: ArbitraryJson -} - -type Query { - fetch(args: MyInput): Int -} -``` - -Then, submitting the query - -``` -query FetchData($myJsonValue: ArbitraryJson) { - fetch(args: { - json: $myJsonValue - }) -} -``` - -and variables - -``` -{ - "myJsonValue": { - "field.with.dots": 1 - } -} -``` - -During scoring, the demand control plugin would attempt to convert the variable structure into a GraphQL-compliant structure requiring valid GraphQL names as keys. The dot characters in the keys however would cause a panic. - -With this fix, only the GraphQL compliant part of the input object is scored, and the arbitrary JSON marked by the custom scalar is scored as an opaque scalar (similar to how built-ins like `Int` or `String` are processed). - -By [@tninesling](https://github.com/tninesling) in https://github.com/apollographql/router/pull/6288 diff --git a/.changesets/fix_tninesling_remove_demand_control_warnings.md b/.changesets/fix_tninesling_remove_demand_control_warnings.md deleted file mode 100644 index 195ad7d04c..0000000000 --- a/.changesets/fix_tninesling_remove_demand_control_warnings.md +++ /dev/null @@ -1,5 +0,0 @@ -### Remove noisy demand control logs ([PR #6192](https://github.com/apollographql/router/pull/6192)) - -Demand control no longer logs warnings when a subgraph response is missing a requested field. - -By [@tninesling](https://github.com/tninesling) in https://github.com/apollographql/router/pull/6192 diff --git a/.changesets/fix_tninesling_typename_resolution.md b/.changesets/fix_tninesling_typename_resolution.md deleted file mode 100644 index 890cb13ff6..0000000000 --- a/.changesets/fix_tninesling_typename_resolution.md +++ /dev/null @@ -1,7 +0,0 @@ -### Fix incorrect overriding of concrete type names with interface names when merging responses ([PR #6250](https://github.com/apollographql/router/pull/6250)) - -When using `@interfaceObject`, differing pieces of data can come back with either concrete types or interface types depending on the source. Previously, receiving the data in a particular order could incorrectly result in the interface name of a type overwriting its concrete name. - -To make the response merging order-agnostic, the router now checks the schema to ensure concrete types are not overwritten with interfaces or less specific types. - -By [@tninesling](https://github.com/tninesling) in https://github.com/apollographql/router/pull/6250 diff --git a/.changesets/maint_bnjjj_feat_854.md b/.changesets/maint_bnjjj_feat_854.md deleted file mode 100644 index 2f5f7a762f..0000000000 --- a/.changesets/maint_bnjjj_feat_854.md +++ /dev/null @@ -1,5 +0,0 @@ -### Add entity caching invalidation configuration metrics ([PR #6286](https://github.com/apollographql/router/pull/6286)) - -We've added metrics for our analytics to know if entity caching invalidation is enabled. - -By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/6286 \ No newline at end of file diff --git a/.changesets/maint_bnjjj_fix_supergraph_events_span.md b/.changesets/maint_bnjjj_fix_supergraph_events_span.md deleted file mode 100644 index a0548cb374..0000000000 --- a/.changesets/maint_bnjjj_fix_supergraph_events_span.md +++ /dev/null @@ -1,5 +0,0 @@ -### Avoid creating stub span for supergraph events if current span exists ([PR #6096](https://github.com/apollographql/router/pull/6096)) - -The router optimized its telemetry implementation by not creating a redundant span when it already has a span available to use the span's extensions for supergraph events. - -By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/6096 \ No newline at end of file diff --git a/.changesets/maint_geal_query_planner_cache_key_improvements.md b/.changesets/maint_geal_query_planner_cache_key_improvements.md deleted file mode 100644 index afb446115a..0000000000 --- a/.changesets/maint_geal_query_planner_cache_key_improvements.md +++ /dev/null @@ -1,8 +0,0 @@ -### Query planner cache key improvements ([Issue #5160](https://github.com/apollographql/router/issues/5160)) - -> [!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. - -Several performance improvements have been implemented for query plan cache key generation. In particular, the distributed cache's key format has changed, which adds prefixes to the different key segments to help in debugging. - -By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/6206 \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index bb4866bf62..2db933defe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,296 @@ 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.58.0] - 2024-11-26 + +> [!IMPORTANT] +> If you have enabled [Distributed query plan caching](https://www.apollographql.com/docs/router/configuration/distributed-caching/#distributed-query-plan-caching), this release contains changes which necessarily alter 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. + +## ๐Ÿš€ Features + +### Support DNS resolution strategy configuration ([PR #6109](https://github.com/apollographql/router/pull/6109)) + +The router now supports a configurable DNS resolution strategy for the URLs of coprocessors and subgraphs. +The new option is called `dns_resolution_strategy` and supports the following values: +* `ipv4_only` - Only query for `A` (IPv4) records. +* `ipv6_only` - Only query for `AAAA` (IPv6) records. +* `ipv4_and_ipv6` - Query for both `A` (IPv4) and `AAAA` (IPv6) records in parallel. +* `ipv6_then_ipv4` - Query for `AAAA` (IPv6) records first; if that fails, query for `A` (IPv4) records. +* `ipv4_then_ipv6`(default) - Query for `A` (IPv4) records first; if that fails, query for `AAAA` (IPv6) records. + +You can change the DNS resolution strategy applied to a subgraph's URL: + +```yaml title="router.yaml" +traffic_shaping: + all: + dns_resolution_strategy: ipv4_then_ipv6 + +``` + +You can also change the DNS resolution strategy applied to a coprocessor's URL: + +```yaml title="router.yaml" +coprocessor: + url: http://coprocessor.example.com:8081 + client: + dns_resolution_strategy: ipv4_then_ipv6 + +``` + +By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6109 + +### Configuration options for HTTP/1 max headers and buffer limits ([PR #6194](https://github.com/apollographql/router/pull/6194)) + +This update introduces configuration options that allow you to adjust the maximum number of HTTP/1 request headers and the maximum buffer size allocated for headers. + +By default, the router accepts HTTP/1 requests with up to 100 headers and allocates ~400 KiB of buffer space to store them. If you need to handle requests with more headers or require a different buffer size, you can now configure these limits in the router's configuration file: +```yaml +limits: + http1_request_max_headers: 200 + http1_request_max_buf_size: 200kib +``` + +If you are using the router as a Rust crate, the `http1_request_max_buf_size` option requires the `hyper_header_limits` feature and also necessitates using Apollo's fork of the Hyper crate until the [changes are merged upstream](https://github.com/hyperium/hyper/pull/3523). +You can include this fork by adding the following patch to your Cargo.toml file: +```toml +[patch.crates-io] +"hyper" = { git = "https://github.com/apollographql/hyper.git", tag = "header-customizations-20241108" } +``` + +By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6194 + +### Compress subgraph operations by generating fragments ([PR #6013](https://github.com/apollographql/router/pull/6013)) + +The router now compresses operations sent to subgraphs by default by generating fragment +definitions and using them in the operation. + +This change enables `generate_query_fragments` by default while disabling `experimental_reuse_query_fragments`. When enabled, `experimental_reuse_query_fragments` attempts to intelligently reuse the fragment definitions +from the original operation. However, fragment generation with `generate_query_fragments` is much faster and produces better outputs in most cases. + +If you are relying on the shape of fragments in your subgraph operations or tests, you can opt out of the new algorithm with the configuration below. + +> Note: The subgraph operations generated by the query planner are not guaranteed consistent release over release. We strongly recommend against relying on the shape of planned subgraph operations, as new router features and optimizations will continuously affect it. We plan to remove `experimental_reuse_query_fragments` in a future release. + +```yaml +supergraph: + generate_query_fragments: false + experimental_reuse_query_fragments: true +``` + +By [@lrlna](https://github.com/lrlna) in https://github.com/apollographql/router/pull/6013 + +### Add subgraph request id ([PR #5858](https://github.com/apollographql/router/pull/5858)) + +The router now supports a subgraph request ID that is a unique string identifying a subgraph request and response. It allows plugins and coprocessors to keep some state per subgraph request by matching on this ID. It's available in coprocessors as `subgraphRequestId` and Rhai scripts as `request.subgraph.id` and `response.subgraph.id`. + + +By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/5858 + +### Add `extensions.service` for all subgraph errors ([PR #6191](https://github.com/apollographql/router/pull/6191)) + + +For improved debuggability, the router now supports adding a subgraph's name as an extension to all errors originating from the subgraph. + +If `include_subgraph_errors` is `true` for a particular subgraph, all errors originating in this subgraph will have the subgraph's name exposed as a `service` extension. + +You can enable subgraph errors with the following configuration: +```yaml title="router.yaml" +include_subgraph_errors: + all: true # Propagate errors from all subgraphs +``` +> Note: This option is enabled by default by the router's [dev mode](https://www.apollographql.com/docs/graphos/reference/router/configuration#dev-mode-defaults). + +Consequently, when a subgraph returns an error, it will have a `service` extension with the subgraph name as its value. The following example shows the extension for a `products` subgraph: + +```json +{ + "data": null, + "errors": [ + { + "message": "Invalid product ID", + "path": [], + "extensions": { + "service": "products" + } + } + ] +} +``` + +By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6191 + +### Add `@context` support in the native query planner ([PR #6310](https://github.com/apollographql/router/pull/6310)) + +The [`@context`](https://www.apollographql.com/docs/graphos/reference/federation/directives#context) feature is now available in the [native query planner](https://www.apollographql.com/docs/graphos/routing/query-planning/native-query-planner). +This brings the native query planner to feature parity with the legacy query planner for all Federation v2 graphs. The native query planner can be enabled with the following configuration: +```yaml, filename=router.yaml +experimental_query_planner_mode: new +``` + + +By [@clenfest](https://github.com/clenfest), [@TylerBloom](https://github.com/TylerBloom) in https://github.com/apollographql/router/pull/6310 + +## ๐Ÿ› Fixes + +### Remove noisy demand control logs ([PR #6192](https://github.com/apollographql/router/pull/6192)) + +Demand control no longer logs warnings when a subgraph response is missing a requested field. + +By [@tninesling](https://github.com/tninesling) in https://github.com/apollographql/router/pull/6192 + +### Renamed headers' original values can again be propagated ([PR #6281](https://github.com/apollographql/router/pull/6281)) + +[PR #4535](https://github.com/apollographql/router/pull/4535) introduced a regression where the following header propagation config would not work: + +```yaml +headers: +- propagate: + named: a + rename: b +- propagate: + named: a + rename: c +``` + +The goal of the original PR was to prevent multiple headers from being mapped to a single target header. However, it did not consider renames and instead prevented multiple mappings from the same source header. +The router now propagates headers properly and ensures that a target header is only propagated to once. + +By [@BrynCooke](https://github.com/BrynCooke) in https://github.com/apollographql/router/pull/6281 + +### Introspection response deduplication should always produce results ([Issue #6249](https://github.com/apollographql/router/issues/6249)) + +To reduce CPU usage, query planning and introspection queries are deduplicated. In some cases, deduplicated introspection queries were not receiving their result. This issue has been fixed, and the router now sends results in all cases. + +By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/6257 + +### Don't log response data upon notification failure for subgraph batching ([PR #6150](https://github.com/apollographql/router/pull/6150)) + +For a subgraph batching operation, the router now doesn't log the entire subgraph response when failing to notify a waiting batch participant. This saves the router from logging the large amount of data (PII and/or non-PII data) that a subgraph response may contain. + +By [@garypen](https://github.com/garypen) in https://github.com/apollographql/router/pull/6150 + +### Move heavy computation to a thread pool with a priority queue ([PR #6247](https://github.com/apollographql/router/pull/6247)) + +The router now avoids blocking threads when executing asynchronous code by using a thread pool with a priority queue. + +This improves the performance of the following components that can take non-trivial amounts of CPU time: + +* GraphQL parsing +* GraphQL validation +* Query planning +* Schema introspection + +The size of the thread pool is based on the number of available CPU cores. + +The thread pool replaces the router's prior implementation that used Tokioโ€™s [`spawn_blocking`](https://docs.rs/tokio/latest/tokio/task/fn.spawn_blocking.html). + +`apollo.router.compute_jobs.queued` is a new gauge metric for the number of items in the thread pool's priority queue. + +> Note: when the native query planner is enabled, the dedicated queue of the legacy query planner is no longer used, so the `apollo.router.query_planning.queued` metric is no longer emitted. + +By [@SimonSapin](https://github.com/SimonSapin) in https://github.com/apollographql/router/pull/6247 + +### Limit the amount of GraphQL validation errors returned per response ([PR #6187](https://github.com/apollographql/router/pull/6187)) + +When an invalid query is submitted, the router now returns at most one hundred GraphQL parsing and validation errors in a response. This prevents generating too large of a response for a nonsensical document. + +By [@goto-bus-stop](https://github.com/goto-bus-stop) in https://github.com/apollographql/router/pull/6187 + +### Remove placeholders from file upload query variables ([PR #6293](https://github.com/apollographql/router/pull/6293)) + +Previously, file upload query variables in subgraph requests incorrectly contained internal placeholders. +According to the [GraphQL Multipart Request Spec](https://github.com/jaydenseric/graphql-multipart-request-spec?tab=readme-ov-file#multipart-form-field-structure), these variables should be set to null. +This issue has been fixed by ensuring that the router complies with the specification and improving compatibility with subgraphs handling file uploads. + +By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6293 + +### Overhead processing metrics should exclude subgraph response time when deduplication is enabled ([PR #6207](https://github.com/apollographql/router/pull/6207)) + +The router's calculated overhead processing time has been fixed, where the time spent waiting for the subgraph response of a deduplicated request had been incorrectly included. + +By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/6207 + +### Fix demand control panic for custom scalars that represent non-GraphQL-compliant JSON ([PR #6288](https://github.com/apollographql/router/pull/6288)) + +Previously, a panic could be triggered in the router's demand control plugin with the following schema: + +``` +scalar ArbitraryJson + +type MyInput { + json: ArbitraryJson +} + +type Query { + fetch(args: MyInput): Int +} +``` + +Then, submitting the query + +``` +query FetchData(: ArbitraryJson) { + fetch(args: { + json: + }) +} +``` + +and variables + +``` +{ + "myJsonValue": { + "field.with.dots": 1 + } +} +``` + +During scoring, the demand control plugin would attempt to convert the variable structure into a GraphQL-compliant structure requiring valid GraphQL names as keys. The dot characters in the keys however would cause a panic. + +With this fix, only the GraphQL compliant part of the input object is scored, and the arbitrary JSON marked by the custom scalar is scored as an opaque scalar (similar to how built-ins like `Int` or `String` are processed). + +By [@tninesling](https://github.com/tninesling) in https://github.com/apollographql/router/pull/6288 + +### Fix incorrect overriding of concrete type names with interface names when merging responses ([PR #6250](https://github.com/apollographql/router/pull/6250)) + +When using `@interfaceObject`, differing pieces of data can come back with either concrete types or interface types depending on the source. Previously, receiving the data in a particular order could incorrectly result in the interface name of a type overwriting its concrete name. + +To make the response merging order-agnostic, the router now checks the schema to ensure concrete types are not overwritten with interfaces or less specific types. + +By [@tninesling](https://github.com/tninesling) in https://github.com/apollographql/router/pull/6250 + +## ๐Ÿ›  Maintenance + +### Query planner cache key improvements ([Issue #5160](https://github.com/apollographql/router/issues/5160)) + +Several performance improvements have been implemented for query plan cache key generation. In particular, the distributed cache's key format has changed, which adds prefixes to the different key segments to help in debugging. + +By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/6206 + +### Add entity caching invalidation configuration metrics ([PR #6286](https://github.com/apollographql/router/pull/6286)) + +We've added metrics for our analytics to know if entity caching invalidation is enabled. + +By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/6286 + +### Avoid creating stub span for supergraph events if current span exists ([PR #6096](https://github.com/apollographql/router/pull/6096)) + +The router optimized its telemetry implementation by not creating a redundant span when it already has a span available to use the span's extensions for supergraph events. + +By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/6096 + +## ๐Ÿ“š Documentation + +### Clarify docs for authorization directive composition ([PR #6216](https://github.com/apollographql/router/pull/6216)) + +The docs for [authorization directive composition](https://www.apollographql.com/docs/graphos/routing/security/authorization#composition-and-federation) have been clarified, including corrected code examples. + + +By [@Meschreiber](https://github.com/Meschreiber) in https://github.com/apollographql/router/pull/6216 + + + # [1.57.1] - 2024-10-31 ## ๐Ÿ› Fixes diff --git a/Cargo.lock b/Cargo.lock index 34e2c836de..57a87514d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -178,7 +178,7 @@ dependencies = [ [[package]] name = "apollo-federation" -version = "1.58.0-rc.2" +version = "1.58.0" dependencies = [ "apollo-compiler", "derive_more", @@ -231,7 +231,7 @@ dependencies = [ [[package]] name = "apollo-router" -version = "1.58.0-rc.2" +version = "1.58.0" dependencies = [ "access-json", "ahash", @@ -399,7 +399,7 @@ dependencies = [ [[package]] name = "apollo-router-benchmarks" -version = "1.58.0-rc.2" +version = "1.58.0" dependencies = [ "apollo-parser", "apollo-router", @@ -415,7 +415,7 @@ dependencies = [ [[package]] name = "apollo-router-scaffold" -version = "1.58.0-rc.2" +version = "1.58.0" dependencies = [ "anyhow", "cargo-scaffold", diff --git a/apollo-federation/Cargo.toml b/apollo-federation/Cargo.toml index e0e8b9150c..c0103f435e 100644 --- a/apollo-federation/Cargo.toml +++ b/apollo-federation/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-federation" -version = "1.58.0-rc.2" +version = "1.58.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 34410cad70..359391b4a7 100644 --- a/apollo-router-benchmarks/Cargo.toml +++ b/apollo-router-benchmarks/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router-benchmarks" -version = "1.58.0-rc.2" +version = "1.58.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 105b1ce0bd..8b68e56a12 100644 --- a/apollo-router-scaffold/Cargo.toml +++ b/apollo-router-scaffold/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router-scaffold" -version = "1.58.0-rc.2" +version = "1.58.0" authors = ["Apollo Graph, Inc. "] edition = "2021" license = "Elastic-2.0" diff --git a/apollo-router-scaffold/templates/base/Cargo.template.toml b/apollo-router-scaffold/templates/base/Cargo.template.toml index 0a181f0008..00b111b264 100644 --- a/apollo-router-scaffold/templates/base/Cargo.template.toml +++ b/apollo-router-scaffold/templates/base/Cargo.template.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.58.0-rc.2" +apollo-router = "1.58.0" {{/if}} {{/if}} async-trait = "0.1.52" diff --git a/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml b/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml index e81afd56d8..db2a939c2a 100644 --- a/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml +++ b/apollo-router-scaffold/templates/base/xtask/Cargo.template.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.58.0-rc.2" } +apollo-router-scaffold = { git = "https://github.com/apollographql/router.git", tag = "v1.58.0" } {{/if}} {{/if}} anyhow = "1.0.58" diff --git a/apollo-router/Cargo.toml b/apollo-router/Cargo.toml index ab3a737fd0..f2cedca917 100644 --- a/apollo-router/Cargo.toml +++ b/apollo-router/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router" -version = "1.58.0-rc.2" +version = "1.58.0" authors = ["Apollo Graph, Inc. "] repository = "https://github.com/apollographql/router/" documentation = "https://docs.rs/apollo-router" @@ -66,7 +66,7 @@ features = ["docs_rs"] access-json = "0.1.0" anyhow = "1.0.86" apollo-compiler.workspace = true -apollo-federation = { path = "../apollo-federation", version = "=1.58.0-rc.2" } +apollo-federation = { path = "../apollo-federation", version = "=1.58.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 1f9bc33cb9..e69604eb8c 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.58.0-rc.2 + image: ghcr.io/apollographql/router:v1.58.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 0a22a025e4..8225d7799a 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.58.0-rc.2 + image: ghcr.io/apollographql/router:v1.58.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 d6230610f5..a84a7f1fcf 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.58.0-rc.2 + image: ghcr.io/apollographql/router:v1.58.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 7ff3a8b8f7..51cf64fa63 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.58.0-rc.2 +version: 1.58.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.58.0-rc.2" +appVersion: "v1.58.0" diff --git a/helm/chart/router/README.md b/helm/chart/router/README.md index 15e2be484d..c68ab5cd8b 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.58.0-rc.2](https://img.shields.io/badge/Version-1.58.0--rc.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.58.0-rc.2](https://img.shields.io/badge/AppVersion-v1.58.0--rc.2-informational?style=flat-square) +![Version: 1.58.0](https://img.shields.io/badge/Version-1.58.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.58.0](https://img.shields.io/badge/AppVersion-v1.58.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.58.0-rc.2 +helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0 ``` ## Install Chart @@ -19,7 +19,7 @@ helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0-rc.2 **Important:** only helm3 is supported ```console -helm upgrade --install [RELEASE_NAME] oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0-rc.2 --values my-values.yaml +helm upgrade --install [RELEASE_NAME] oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0 --values my-values.yaml ``` _See [configuration](#configuration) below._ diff --git a/licenses.html b/licenses.html index 37ceccad5d..8d5e68ad9f 100644 --- a/licenses.html +++ b/licenses.html @@ -44,13 +44,13 @@

      Third Party Licenses

      Overview of licenses:

        -
      • Apache License 2.0 (445)
      • -
      • MIT License (154)
      • +
      • Apache License 2.0 (430)
      • +
      • MIT License (145)
      • BSD 3-Clause "New" or "Revised" License (11)
      • ISC License (8)
      • -
      • Elastic License 2.0 (6)
      • Mozilla Public License 2.0 (5)
      • BSD 2-Clause "Simplified" License (4)
      • +
      • Elastic License 2.0 (3)
      • Creative Commons Zero v1.0 Universal (2)
      • OpenSSL License (1)
      • Unicode License Agreement - Data Files and Software (2016) (1)
      • @@ -66,7 +66,6 @@

        Used by:

      • aws-config
      • aws-credential-types
      • aws-runtime
      • -
      • aws-sigv4
      • aws-smithy-async
      • aws-smithy-http
      • aws-smithy-json
      • @@ -1718,8 +1717,6 @@

        Used by:

        Apache License 2.0

        Used by:

        @@ -1943,191 +1940,6 @@

        Used by:

        the License, but only in their entirety and only with respect to the Combined Software. - - -
      • -

        Apache License 2.0

        -

        Used by:

        - -
        -                                 Apache License
        -                           Version 2.0, January 2004
        -                        https://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
         
      • @@ -3197,7 +3009,6 @@

        Used by:

      • clap_builder
      • clap_derive
      • clap_lex
      • -
      • opentelemetry-proto
                                       Apache License
                                  Version 2.0, January 2004
      @@ -5712,7 +5523,6 @@ 

      Used by:

    14. utf-8
    15. utf8parse
    16. wasm-streams
    17. -
    18. zerocopy
    19.                               Apache License
                               Version 2.0, January 2004
      @@ -8432,7 +8242,6 @@ 

      Used by:

    20. bytes-utils
    21. cc
    22. cfg-if
    23. -
    24. ci_info
    25. cmake
    26. concurrent-queue
    27. const-random
    28. @@ -8447,7 +8256,6 @@

      Used by:

    29. derive_arbitrary
    30. displaydoc
    31. either
    32. -
    33. envmnt
    34. equivalent
    35. event-listener
    36. fastrand
    37. @@ -8458,7 +8266,6 @@

      Used by:

    38. fnv
    39. form_urlencoded
    40. fraction
    41. -
    42. fsio
    43. futures-lite
    44. futures-timer
    45. gimli
    46. @@ -11257,53 +11064,6 @@

      Used by:

      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. -
      -
    47. -
    48. -

      Apache License 2.0

      -

      Used by:

      - -
      # Contributing
      -
      -## License
      -
      -Licensed under either of
      -
      - * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
      - * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
      -
      -at your option.
      -
      -### Contribution
      -
      -Unless you explicitly state otherwise, any contribution intentionally submitted
      -for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
      -additional terms or conditions.
      -
      -
    49. -
    50. -

      Apache License 2.0

      -

      Used by:

      - -
      ../../LICENSE-APACHE
      -
    51. -
    52. -

      Apache License 2.0

      -

      Used by:

      - -
      // Licensed under the Apache License, Version 2.0
      -// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
      -// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
      -// All files in the project carrying such notice may not be copied, modified, or distributed
      -// except according to those terms.
       
    53. @@ -11940,10 +11700,14 @@

      Used by:

      Apache License 2.0

      Used by:

        +
      • apollo-compiler
      • +
      • apollo-parser
      • +
      • apollo-smith
      • async-graphql-axum
      • async-graphql-derive
      • async-graphql-parser
      • async-graphql-value
      • +
      • buildstructor
      • deno-proc-macro-rules
      • deno-proc-macro-rules-macros
      • dunce
      • @@ -11959,6 +11723,7 @@

        Used by:

      • num-cmp
      • prost
      • rhai_codegen
      • +
      • serde_derive_default
      • siphasher
      • system-configuration
      • system-configuration-sys
      • @@ -12041,48 +11806,6 @@

        Used by:

        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:

        - -
        Copyright [2022] [Bryn Cooke]
        -
        -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:

        - -
        Copyright [2023] [Bryn Cooke]
        -
        -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.
        @@ -12105,33 +11828,6 @@ 

        Used by:

        at your option. All files in the project carrying such notice may not be copied, modified, or distributed except according to those terms. -
        -
      • -
      • -

        Apache License 2.0

        -

        Used by:

        - -
        MIT OR Apache-2.0
        -
      • -
      • -

        Apache License 2.0

        -

        Used by:

        - -
        MIT OR Apache-2.0
        -
        -
      • -
      • -

        Apache License 2.0

        -

        Used by:

        - -
        MIT or Apache-2.0
         
      • @@ -12694,9 +12390,6 @@

        Elastic License 2.0

        Used by:

        Copyright 2021 Apollo Graph, Inc.
         
        @@ -12961,6 +12654,36 @@ 

        Used by:

        // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +
        +
      • +
      • +

        ISC License

        +

        Used by:

        + +
        // Copyright 2021 Brian Smith.
        +//
        +// Permission to use, copy, modify, and/or distribute this software for any
        +// purpose with or without fee is hereby granted, provided that the above
        +// copyright notice and this permission notice appear in all copies.
        +//
        +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
        +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
        +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
        +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
        +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        +
        +#[test]
        +fn cert_without_extensions_test() {
        +    // Check the certificate is valid with
        +    // `openssl x509 -in cert_without_extensions.der -inform DER -text -noout`
        +    const CERT_WITHOUT_EXTENSIONS_DER: &[u8] = include_bytes!("cert_without_extensions.der");
        +
        +    assert!(webpki::EndEntityCert::try_from(CERT_WITHOUT_EXTENSIONS_DER).is_ok());
        +}
         
      • @@ -13030,7 +12753,6 @@

        ISC License

        Used by:

        ISC License:
         
        @@ -13752,66 +13474,6 @@ 

        Used by:

        shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. -
        -
      • -
      • -

        MIT License

        -

        Used by:

        - -
        Copyright (c) 2019 Carl Lerche
        -
        -Permission is hereby granted, free of charge, to any
        -person obtaining a copy of this software and associated
        -documentation files (the "Software"), to deal in the
        -Software without restriction, including without
        -limitation the rights to use, copy, modify, merge,
        -publish, distribute, sublicense, and/or sell copies of
        -the Software, and to permit persons to whom the Software
        -is furnished to do so, subject to the following
        -conditions:
        -
        -The above copyright notice and this permission notice
        -shall be included in all copies or substantial portions
        -of the Software.
        -
        -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
        -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
        -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
        -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
        -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
        -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
        -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
        -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
        -DEALINGS IN THE SOFTWARE.
        -
        -Copyright (c) 2018 David Tolnay
        -
        -Permission is hereby granted, free of charge, to any
        -person obtaining a copy of this software and associated
        -documentation files (the "Software"), to deal in the
        -Software without restriction, including without
        -limitation the rights to use, copy, modify, merge,
        -publish, distribute, sublicense, and/or sell copies of
        -the Software, and to permit persons to whom the Software
        -is furnished to do so, subject to the following
        -conditions:
        -
        -The above copyright notice and this permission notice
        -shall be included in all copies or substantial portions
        -of the Software.
        -
         THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
         ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
         TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
        @@ -14818,6 +14480,8 @@ 

        Used by:

        MIT License

        Used by:

          +
        • async-stream
        • +
        • async-stream-impl
        • base64-simd
        • convert_case
        • cookie-factory
        • @@ -15160,8 +14824,6 @@

          Used by:

          The MIT License (MIT)
           
          @@ -15660,14 +15322,7 @@ 

          Used by:

          MIT License

          Used by:

          This project is dual-licensed under the Unlicense and MIT licenses.
           
          @@ -16069,6 +15724,7 @@ 

          Used by:

          Mozilla Public License 2.0

          Used by:

          Mozilla Public License Version 2.0
          @@ -16451,8 +16107,8 @@ 

          Used by:

          Mozilla Public License 2.0

          Used by:

          Mozilla Public License Version 2.0
           ==================================
          @@ -16827,35 +16483,6 @@ 

          Used by:

          This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. -
          - -
        • -

          Mozilla Public License 2.0

          -

          Used by:

          - -
          This packge contains a modified version of ca-bundle.crt:
          -
          -ca-bundle.crt -- Bundle of CA Root Certificates
          -
          -Certificate data from Mozilla as of: Thu Nov  3 19:04:19 2011#
          -This is a bundle of X.509 certificates of public Certificate Authorities
          -(CA). These were automatically extracted from Mozilla's root certificates
          -file (certdata.txt).  This file can be found in the mozilla source tree:
          -http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1#
          -It contains the certificates in PEM format and therefore
          -can be directly used with curl / libcurl / php_curl, or with
          -an Apache+mod_ssl webserver for SSL client authentication.
          -Just configure this file as the SSLCACertificateFile.#
          -
          -***** BEGIN LICENSE BLOCK *****
          -This Source Code Form is subject to the terms of the Mozilla Public License,
          -v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain
          -one at http://mozilla.org/MPL/2.0/.
          -
          -***** END LICENSE BLOCK *****
          -@(#) $RCSfile: certdata.txt,v $ $Revision: 1.80 $ $Date: 2011/11/03 15:11:58 $
           
        • diff --git a/scripts/install.sh b/scripts/install.sh index a1b50a9ae3..6446019f5b 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.58.0-rc.2" +PACKAGE_VERSION="v1.58.0" download_binary() { downloader --check From b09cbd707c377cdecee92d53f3cf19f02230ca8f Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Tue, 26 Nov 2024 16:51:27 +0200 Subject: [PATCH 67/77] Manually fix changeset for #5545 which didn't have the `feat_` prefix. --- .changesets/helm_host_configuration.md | 5 ----- CHANGELOG.md | 6 ++++++ 2 files changed, 6 insertions(+), 5 deletions(-) delete mode 100644 .changesets/helm_host_configuration.md diff --git a/.changesets/helm_host_configuration.md b/.changesets/helm_host_configuration.md deleted file mode 100644 index e26bdc6dd1..0000000000 --- a/.changesets/helm_host_configuration.md +++ /dev/null @@ -1,5 +0,0 @@ -### Allow configuring host via Helm template for virtual service ([PR #5545](https://github.com/apollographql/router/pull/5795)) - -When deploying via Helm, you can now configure hosts in `virtualservice.yaml` as a single host or a range of hosts. This is helpful when different hosts could be used within a cluster. - -By [@nicksephora](https://github.com/nicksephora) in https://github.com/apollographql/router/pull/5545 diff --git a/CHANGELOG.md b/CHANGELOG.md index 2db933defe..03f01f8e28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -133,6 +133,12 @@ experimental_query_planner_mode: new By [@clenfest](https://github.com/clenfest), [@TylerBloom](https://github.com/TylerBloom) in https://github.com/apollographql/router/pull/6310 +### Allow configuring host via Helm template for virtual service ([PR #5545](https://github.com/apollographql/router/pull/5795)) + +When deploying via Helm, you can now configure hosts in `virtualservice.yaml` as a single host or a range of hosts. This is helpful when different hosts could be used within a cluster. + +By [@nicksephora](https://github.com/nicksephora) in https://github.com/apollographql/router/pull/5545 + ## ๐Ÿ› Fixes ### Remove noisy demand control logs ([PR #6192](https://github.com/apollographql/router/pull/6192)) From 3ad59ca1787b07753f69d1fa869ba404b9cc72f7 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Tue, 26 Nov 2024 20:06:52 +0200 Subject: [PATCH 68/77] Trying to recover after CircleCI outage --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 011910e56e..7ac54d7d6e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,6 +1,6 @@ version: 2.1 -# Cache key bump: 1 +# Cache key bump: 0 # These "CircleCI Orbs" are reusable bits of configuration that can be shared # across projects. See https://circleci.com/orbs/ for more information. From 0d57ec6847cffe5be72ed2aa7d3b86e66140780d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e?= Date: Wed, 27 Nov 2024 11:10:21 +0000 Subject: [PATCH 69/77] ci: fix windows runs (#6347) --- .circleci/config.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7ac54d7d6e..8985f1e1ed 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -249,9 +249,15 @@ commands: - run: name: Install CMake command: | - choco install cmake.install -y + choco install cmake -y echo 'export PATH="/c/Program Files/CMake/bin:$PATH"' >> "$BASH_ENV" - exit $LASTEXITCODE + SAVED_EXIT_CODE=$LASTEXITCODE + + source "$BASH_ENV" + echo "Test CMake -- if this fails, play around with chocolatey, I guess." + cmake --version + + exit $SAVED_EXIT_CODE - when: condition: or: @@ -1042,6 +1048,7 @@ workflows: matrix: parameters: platform: [ amd_linux_build ] + - test: # this should be changed back to true on dev after release fuzz: false From cc65cfd0be7173971b4129821d34db420b2c060a Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 27 Nov 2024 13:39:33 +0200 Subject: [PATCH 70/77] Bump cache key after the Windows fix. --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 8985f1e1ed..e5bba6b9be 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,6 +1,6 @@ version: 2.1 -# Cache key bump: 0 +# Cache key bump: 2 # These "CircleCI Orbs" are reusable bits of configuration that can be shared # across projects. See https://circleci.com/orbs/ for more information. From f827d00b41ee064747a3c588a8d4b21a3757676f Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 27 Nov 2024 14:07:38 +0200 Subject: [PATCH 71/77] Bump CI version --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e5bba6b9be..f72d53814e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -76,13 +76,13 @@ executors: parameters: toolchain_version: type: string - default: '{{ checksum ".circleci/config.yml" }}-v2-{{ checksum "~/.arch" }}-{{ checksum "rust-toolchain.toml" }}-{{ checksum "~/.daily_version" }}' + default: '{{ checksum ".circleci/config.yml" }}-v3-{{ checksum "~/.arch" }}-{{ checksum "rust-toolchain.toml" }}-{{ checksum "~/.daily_version" }}' xtask_version: type: string - default: '{{ checksum ".circleci/config.yml" }}-{{ checksum "~/.arch" }}-{{ checksum "rust-toolchain.toml" }}-{{ checksum "~/.xtask_version" }}' + default: '{{ checksum ".circleci/config.yml" }}-v3-{{ checksum "~/.arch" }}-{{ checksum "rust-toolchain.toml" }}-{{ checksum "~/.xtask_version" }}' merge_version: type: string - default: '{{ checksum ".circleci/config.yml" }}-{{ checksum "~/.arch" }}-{{ checksum "rust-toolchain.toml" }}-{{ checksum "~/.xtask_version" }}-{{ checksum "~/.merge_version" }}' + default: '{{ checksum ".circleci/config.yml" }}-v3-{{ checksum "~/.arch" }}-{{ checksum "rust-toolchain.toml" }}-{{ checksum "~/.xtask_version" }}-{{ checksum "~/.merge_version" }}' protoc_version: type: string default: "21.8" From 95cc925091c303c83b90f76ac1f1cc3761af16a3 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 27 Nov 2024 15:44:51 +0200 Subject: [PATCH 72/77] ci: Upgrade build/test environments to macOS v14.3.1 and Xcode v15.4.0 (#6349) --- .circleci/config.yml | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index f72d53814e..95f0026772 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -48,18 +48,14 @@ executors: # See https://circleci.com/docs/xcode-policy along with the support matrix # at https://circleci.com/docs/using-macos#supported-xcode-versions. # We use the major.minor notation to bring in compatible patches. - xcode: "14.2.0" + xcode: "15.4.0" resource_class: macos.m1.large.gen1 macos_test: &macos_test_executor macos: # See https://circleci.com/docs/xcode-policy along with the support matrix # at https://circleci.com/docs/using-macos#supported-xcode-versions. # We use the major.minor notation to bring in compatible patches. - # - # TODO: remove workaround added in https://github.com/apollographql/router/pull/5462 - # once we update to Xcode >= 15.1.0 - # See: https://github.com/apollographql/router/pull/5462 - xcode: "14.2.0" + xcode: "15.4.0" resource_class: macos.m1.large.gen1 windows_build: &windows_build_executor machine: @@ -512,10 +508,6 @@ commands: environment: # Use the settings from the "ci" profile in nextest configuration. NEXTEST_PROFILE: ci - # Temporary disable lib backtrace since it crashing on MacOS - # TODO: remove this workaround once we update to Xcode >= 15.1.0 - # See: https://github.com/apollographql/router/pull/5462 - RUST_LIB_BACKTRACE: 0 command: xtask test --workspace --locked --features ci,hyper_header_limits - run: name: Delete large files from cache From b537cd6175fb52bdb3fa39ae66566ce368d21d61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e?= Date: Wed, 27 Nov 2024 15:03:52 +0000 Subject: [PATCH 73/77] ci: install cmake straight from github on windows (#6348) --- .circleci/config.yml | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 95f0026772..126c85a25d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -82,6 +82,10 @@ parameters: protoc_version: type: string default: "21.8" + # note the cmake version is only used for manual installs, not for installs from a package manager like apt or homebrew + cmake_version: + type: string + default: "3.31.1" nightly: type: boolean default: false @@ -245,15 +249,15 @@ commands: - run: name: Install CMake command: | - choco install cmake -y - echo 'export PATH="/c/Program Files/CMake/bin:$PATH"' >> "$BASH_ENV" - SAVED_EXIT_CODE=$LASTEXITCODE + mkdir -p "$HOME/.local" + if [[ ! -f "$HOME/.local/bin/cmake" ]]; then + curl -L https://github.com/Kitware/CMake/releases/download/v<< pipeline.parameters.cmake_version >>/cmake-<< pipeline.parameters.cmake_version >>-windows-x86_64.zip --output cmake.zip + # The zip file has a root directory, so we put it somewhere else first before placing the files in .local + unzip cmake.zip -d /tmp > /dev/null + cp /tmp/cmake-<< pipeline.parameters.cmake_version >>-windows-x86_64/* -R "$HOME/.local" + fi - source "$BASH_ENV" - echo "Test CMake -- if this fails, play around with chocolatey, I guess." cmake --version - - exit $SAVED_EXIT_CODE - when: condition: or: From 58893b745c3fbaa3ebcb57033394c1d9529bdb6d Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 27 Nov 2024 15:56:48 +0200 Subject: [PATCH 74/77] Revert "Manually fix changeset for #5545 which didn't have the `feat_` prefix." This reverts commit b09cbd707c377cdecee92d53f3cf19f02230ca8f. --- .changesets/helm_host_configuration.md | 5 +++++ CHANGELOG.md | 6 ------ 2 files changed, 5 insertions(+), 6 deletions(-) create mode 100644 .changesets/helm_host_configuration.md diff --git a/.changesets/helm_host_configuration.md b/.changesets/helm_host_configuration.md new file mode 100644 index 0000000000..e26bdc6dd1 --- /dev/null +++ b/.changesets/helm_host_configuration.md @@ -0,0 +1,5 @@ +### Allow configuring host via Helm template for virtual service ([PR #5545](https://github.com/apollographql/router/pull/5795)) + +When deploying via Helm, you can now configure hosts in `virtualservice.yaml` as a single host or a range of hosts. This is helpful when different hosts could be used within a cluster. + +By [@nicksephora](https://github.com/nicksephora) in https://github.com/apollographql/router/pull/5545 diff --git a/CHANGELOG.md b/CHANGELOG.md index 03f01f8e28..2db933defe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -133,12 +133,6 @@ experimental_query_planner_mode: new By [@clenfest](https://github.com/clenfest), [@TylerBloom](https://github.com/TylerBloom) in https://github.com/apollographql/router/pull/6310 -### Allow configuring host via Helm template for virtual service ([PR #5545](https://github.com/apollographql/router/pull/5795)) - -When deploying via Helm, you can now configure hosts in `virtualservice.yaml` as a single host or a range of hosts. This is helpful when different hosts could be used within a cluster. - -By [@nicksephora](https://github.com/nicksephora) in https://github.com/apollographql/router/pull/5545 - ## ๐Ÿ› Fixes ### Remove noisy demand control logs ([PR #6192](https://github.com/apollographql/router/pull/6192)) From f080e3cac03a2a0f768ba5552fb750895a902c64 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 27 Nov 2024 15:58:09 +0200 Subject: [PATCH 75/77] Revert "prep release: v1.58.0 (#6331)" This reverts commit eeb63ec988bdd8936b3af38ddd3ad19c5a94f05d. --- ...ify_authorization_directive_composition.md | 6 + .../feat_add_dns_resolution_strategy.md | 30 ++ .changesets/feat_error_extensions_service.md | 32 ++ .changesets/feat_geal_subgraph_request_id.md | 6 + ...ble_generate_query_fragments_by_default.md | 19 + .changesets/feat_max_headers.md | 19 + .../feat_router_528_impl_set_context.md | 6 + .../fix_bryn_fix_header_propagation.md | 18 + ...ix_fix_file_upload_variable_placeholder.md | 7 + ...en_log_less_error_for_subgraph_batching.md | 5 + .../fix_geal_deduplication_processing_time.md | 5 + .../fix_geal_introspection_dedup_fix.md | 5 + .changesets/fix_renee_limit_errors.md | 5 + .changesets/fix_simon_compute_jobs.md | 21 + ...nesling_demand_control_variable_scoring.md | 41 ++ ...inesling_remove_demand_control_warnings.md | 5 + .../fix_tninesling_typename_resolution.md | 7 + .changesets/maint_bnjjj_feat_854.md | 5 + .../maint_bnjjj_fix_supergraph_events_span.md | 5 + ...al_query_planner_cache_key_improvements.md | 8 + CHANGELOG.md | 290 ----------- Cargo.lock | 8 +- apollo-federation/Cargo.toml | 2 +- apollo-router-benchmarks/Cargo.toml | 2 +- apollo-router-scaffold/Cargo.toml | 2 +- .../templates/base/Cargo.template.toml | 2 +- .../templates/base/xtask/Cargo.template.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 | 6 +- licenses.html | 457 ++++++++++++++++-- scripts/install.sh | 2 +- 35 files changed, 690 insertions(+), 352 deletions(-) create mode 100644 .changesets/docs_clarify_authorization_directive_composition.md create mode 100644 .changesets/feat_add_dns_resolution_strategy.md create mode 100644 .changesets/feat_error_extensions_service.md create mode 100644 .changesets/feat_geal_subgraph_request_id.md create mode 100644 .changesets/feat_lrlna_enable_generate_query_fragments_by_default.md create mode 100644 .changesets/feat_max_headers.md create mode 100644 .changesets/feat_router_528_impl_set_context.md create mode 100644 .changesets/fix_bryn_fix_header_propagation.md create mode 100644 .changesets/fix_fix_file_upload_variable_placeholder.md create mode 100644 .changesets/fix_garypen_log_less_error_for_subgraph_batching.md create mode 100644 .changesets/fix_geal_deduplication_processing_time.md create mode 100644 .changesets/fix_geal_introspection_dedup_fix.md create mode 100644 .changesets/fix_renee_limit_errors.md create mode 100644 .changesets/fix_simon_compute_jobs.md create mode 100644 .changesets/fix_tninesling_demand_control_variable_scoring.md create mode 100644 .changesets/fix_tninesling_remove_demand_control_warnings.md create mode 100644 .changesets/fix_tninesling_typename_resolution.md create mode 100644 .changesets/maint_bnjjj_feat_854.md create mode 100644 .changesets/maint_bnjjj_fix_supergraph_events_span.md create mode 100644 .changesets/maint_geal_query_planner_cache_key_improvements.md diff --git a/.changesets/docs_clarify_authorization_directive_composition.md b/.changesets/docs_clarify_authorization_directive_composition.md new file mode 100644 index 0000000000..5413e0234e --- /dev/null +++ b/.changesets/docs_clarify_authorization_directive_composition.md @@ -0,0 +1,6 @@ +### Clarify docs for authorization directive composition ([PR #6216](https://github.com/apollographql/router/pull/6216)) + +The docs for [authorization directive composition](https://www.apollographql.com/docs/graphos/routing/security/authorization#composition-and-federation) have been clarified, including corrected code examples. + + +By [@Meschreiber](https://github.com/Meschreiber) in https://github.com/apollographql/router/pull/6216 diff --git a/.changesets/feat_add_dns_resolution_strategy.md b/.changesets/feat_add_dns_resolution_strategy.md new file mode 100644 index 0000000000..399865ced1 --- /dev/null +++ b/.changesets/feat_add_dns_resolution_strategy.md @@ -0,0 +1,30 @@ +### Support DNS resolution strategy configuration ([PR #6109](https://github.com/apollographql/router/pull/6109)) + +The router now supports a configurable DNS resolution strategy for the URLs of coprocessors and subgraphs. +The new option is called `dns_resolution_strategy` and supports the following values: +* `ipv4_only` - Only query for `A` (IPv4) records. +* `ipv6_only` - Only query for `AAAA` (IPv6) records. +* `ipv4_and_ipv6` - Query for both `A` (IPv4) and `AAAA` (IPv6) records in parallel. +* `ipv6_then_ipv4` - Query for `AAAA` (IPv6) records first; if that fails, query for `A` (IPv4) records. +* `ipv4_then_ipv6`(default) - Query for `A` (IPv4) records first; if that fails, query for `AAAA` (IPv6) records. + +You can change the DNS resolution strategy applied to a subgraph's URL: + +```yaml title="router.yaml" +traffic_shaping: + all: + dns_resolution_strategy: ipv4_then_ipv6 + +``` + +You can also change the DNS resolution strategy applied to a coprocessor's URL: + +```yaml title="router.yaml" +coprocessor: + url: http://coprocessor.example.com:8081 + client: + dns_resolution_strategy: ipv4_then_ipv6 + +``` + +By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6109 diff --git a/.changesets/feat_error_extensions_service.md b/.changesets/feat_error_extensions_service.md new file mode 100644 index 0000000000..e8a1e09031 --- /dev/null +++ b/.changesets/feat_error_extensions_service.md @@ -0,0 +1,32 @@ +### Add `extensions.service` for all subgraph errors ([PR #6191](https://github.com/apollographql/router/pull/6191)) + + +For improved debuggability, the router now supports adding a subgraph's name as an extension to all errors originating from the subgraph. + +If `include_subgraph_errors` is `true` for a particular subgraph, all errors originating in this subgraph will have the subgraph's name exposed as a `service` extension. + +You can enable subgraph errors with the following configuration: +```yaml title="router.yaml" +include_subgraph_errors: + all: true # Propagate errors from all subgraphs +``` +> Note: This option is enabled by default by the router's [dev mode](https://www.apollographql.com/docs/graphos/reference/router/configuration#dev-mode-defaults). + +Consequently, when a subgraph returns an error, it will have a `service` extension with the subgraph name as its value. The following example shows the extension for a `products` subgraph: + +```json +{ + "data": null, + "errors": [ + { + "message": "Invalid product ID", + "path": [], + "extensions": { + "service": "products" + } + } + ] +} +``` + +By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6191 \ No newline at end of file diff --git a/.changesets/feat_geal_subgraph_request_id.md b/.changesets/feat_geal_subgraph_request_id.md new file mode 100644 index 0000000000..07d85f8efd --- /dev/null +++ b/.changesets/feat_geal_subgraph_request_id.md @@ -0,0 +1,6 @@ +### Add subgraph request id ([PR #5858](https://github.com/apollographql/router/pull/5858)) + +The router now supports a subgraph request ID that is a unique string identifying a subgraph request and response. It allows plugins and coprocessors to keep some state per subgraph request by matching on this ID. It's available in coprocessors as `subgraphRequestId` and Rhai scripts as `request.subgraph.id` and `response.subgraph.id`. + + +By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/5858 \ No newline at end of file diff --git a/.changesets/feat_lrlna_enable_generate_query_fragments_by_default.md b/.changesets/feat_lrlna_enable_generate_query_fragments_by_default.md new file mode 100644 index 0000000000..d541706cd9 --- /dev/null +++ b/.changesets/feat_lrlna_enable_generate_query_fragments_by_default.md @@ -0,0 +1,19 @@ +### Compress subgraph operations by generating fragments ([PR #6013](https://github.com/apollographql/router/pull/6013)) + +The router now compresses operations sent to subgraphs by default by generating fragment +definitions and using them in the operation. + +This change enables `generate_query_fragments` by default while disabling `experimental_reuse_query_fragments`. When enabled, `experimental_reuse_query_fragments` attempts to intelligently reuse the fragment definitions +from the original operation. However, fragment generation with `generate_query_fragments` is much faster also produces better outputs in most cases. + +If you are relying on the shape of fragments in your subgraph operations or tests, you can opt out of the new algorithm with the configuration below. + +> Note: The subgraph operations generated by the query planner are not guaranteed consistent release over release. We strongly recommend against relying on the shape of planned subgraph operations, as new router features and optimizations will continuously affect it. We plan to remove `experimental_reuse_query_fragments` in a future release. + +```yaml +supergraph: + generate_query_fragments: false + experimental_reuse_query_fragments: true +``` + +By [@lrlna](https://github.com/lrlna) in https://github.com/apollographql/router/pull/6013 diff --git a/.changesets/feat_max_headers.md b/.changesets/feat_max_headers.md new file mode 100644 index 0000000000..97c58995a7 --- /dev/null +++ b/.changesets/feat_max_headers.md @@ -0,0 +1,19 @@ +### Configuration options for HTTP/1 max headers and buffer limits ([PR #6194](https://github.com/apollographql/router/pull/6194)) + +This update introduces configuration options that allow you to adjust the maximum number of HTTP/1 request headers and the maximum buffer size allocated for headers. + +By default, the router accepts HTTP/1 requests with up to 100 headers and allocates ~400 KiB of buffer space to store them. If you need to handle requests with more headers or require a different buffer size, you can now configure these limits in the router's configuration file: +```yaml +limits: + http1_request_max_headers: 200 + http1_request_max_buf_size: 200kib +``` + +If you are using the router as a Rust crate, the `http1_request_max_buf_size` option requires the `hyper_header_limits` feature and also necessitates using Apollo's fork of the Hyper crate until the [changes are merged upstream](https://github.com/hyperium/hyper/pull/3523). +You can include this fork by adding the following patch to your Cargo.toml file: +```toml +[patch.crates-io] +"hyper" = { git = "https://github.com/apollographql/hyper.git", tag = "header-customizations-20241108" } +``` + +By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6194 diff --git a/.changesets/feat_router_528_impl_set_context.md b/.changesets/feat_router_528_impl_set_context.md new file mode 100644 index 0000000000..b805deca59 --- /dev/null +++ b/.changesets/feat_router_528_impl_set_context.md @@ -0,0 +1,6 @@ +### Add `@context` support in the native query planner ([PR #6310](https://github.com/apollographql/router/pull/6310)) + +The [`@context`](https://www.apollographql.com/docs/graphos/reference/federation/directives#context) feature is now available in the native query planner. +This brings the native query planner to feature parity with the legacy query planner for all Federation v2 graphs. + +By [@clenfest](https://github.com/clenfest), [@TylerBloom](https://github.com/TylerBloom) in https://github.com/apollographql/router/pull/6310 \ No newline at end of file diff --git a/.changesets/fix_bryn_fix_header_propagation.md b/.changesets/fix_bryn_fix_header_propagation.md new file mode 100644 index 0000000000..fe402a26c6 --- /dev/null +++ b/.changesets/fix_bryn_fix_header_propagation.md @@ -0,0 +1,18 @@ +### Renamed headers' original values can again be propagated ([PR #6281](https://github.com/apollographql/router/pull/6281)) + +[PR #4535](https://github.com/apollographql/router/pull/4535) introduced a regression where the following header propagation config would not work: + +```yaml +headers: +- propagate: + named: a + rename: b +- propagate: + named: a + rename: c +``` + +The goal of the original PR was to prevent multiple headers from being mapped to a single target header. However, it did not consider renames and instead prevented multiple mappings from the same source header. +The router now propagates headers properly and ensures that a target header is only propagated to once. + +By [@BrynCooke](https://github.com/BrynCooke) in https://github.com/apollographql/router/pull/6281 diff --git a/.changesets/fix_fix_file_upload_variable_placeholder.md b/.changesets/fix_fix_file_upload_variable_placeholder.md new file mode 100644 index 0000000000..2e7dc5a521 --- /dev/null +++ b/.changesets/fix_fix_file_upload_variable_placeholder.md @@ -0,0 +1,7 @@ +### Remove placeholders from file upload query variables ([PR #6293](https://github.com/apollographql/router/pull/6293)) + +Previously, file upload query variables in subgraph requests incorrectly contained internal placeholders. +According to the [GraphQL Multipart Request Spec](https://github.com/jaydenseric/graphql-multipart-request-spec?tab=readme-ov-file#multipart-form-field-structure), these variables should be set to null. +This issue has been fixed by ensuring that the router complies with the specification and improving compatibility with subgraphs handling file uploads. + +By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6293 diff --git a/.changesets/fix_garypen_log_less_error_for_subgraph_batching.md b/.changesets/fix_garypen_log_less_error_for_subgraph_batching.md new file mode 100644 index 0000000000..9f7d8d1628 --- /dev/null +++ b/.changesets/fix_garypen_log_less_error_for_subgraph_batching.md @@ -0,0 +1,5 @@ +### Don't log response data upon notification failure for subgraph batching ([PR #6150](https://github.com/apollographql/router/pull/6150)) + +For a subgraph batching operation, the router now doesn't log the entire subgraph response when failing to notify a waiting batch participant. This saves the router from logging the large amount of data (PII and/or non-PII data) that a subgraph response may contain. + +By [@garypen](https://github.com/garypen) in https://github.com/apollographql/router/pull/6150 \ No newline at end of file diff --git a/.changesets/fix_geal_deduplication_processing_time.md b/.changesets/fix_geal_deduplication_processing_time.md new file mode 100644 index 0000000000..71e10b87ed --- /dev/null +++ b/.changesets/fix_geal_deduplication_processing_time.md @@ -0,0 +1,5 @@ +### Overhead processing metrics should exclude subgraph response time when deduplication is enabled ([PR #6207](https://github.com/apollographql/router/pull/6207)) + +The router's calculated overhead processing time has been fixed, where the time spent waiting for the subgraph response of a deduplicated request had been incorrectly included. + +By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/6207 \ No newline at end of file diff --git a/.changesets/fix_geal_introspection_dedup_fix.md b/.changesets/fix_geal_introspection_dedup_fix.md new file mode 100644 index 0000000000..3fc10a3748 --- /dev/null +++ b/.changesets/fix_geal_introspection_dedup_fix.md @@ -0,0 +1,5 @@ +### Introspection response deduplication should always produce results ([Issue #6249](https://github.com/apollographql/router/issues/6249)) + +To reduce CPU usage, query planning and introspection queries are deduplicated. In some cases, deduplicated introspection queries were not receiving their result. This issue has been fixed, and the router now sends results in all cases. + +By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/6257 \ No newline at end of file diff --git a/.changesets/fix_renee_limit_errors.md b/.changesets/fix_renee_limit_errors.md new file mode 100644 index 0000000000..c2df146205 --- /dev/null +++ b/.changesets/fix_renee_limit_errors.md @@ -0,0 +1,5 @@ +### Limit the amount of GraphQL validation errors returned per response ([PR #6187](https://github.com/apollographql/router/pull/6187)) + +When an invalid query is submitted, the router now returns at most one hundred GraphQL parsing and validation errors in a response. This prevents generating too large of a response for a nonsensical document. + +By [@goto-bus-stop](https://github.com/goto-bus-stop) in https://github.com/apollographql/router/pull/6187 \ No newline at end of file diff --git a/.changesets/fix_simon_compute_jobs.md b/.changesets/fix_simon_compute_jobs.md new file mode 100644 index 0000000000..ac7f1fccaa --- /dev/null +++ b/.changesets/fix_simon_compute_jobs.md @@ -0,0 +1,21 @@ +### Move heavy computation to a thread pool with a priority queue ([PR #6247](https://github.com/apollographql/router/pull/6247)) + +The router now avoids blocking threads when executing asynchronous code by using a thread pool with a priority queue. + +This improves the performance of the following components can take non-trivial amounts of CPU time: + +* GraphQL parsing +* GraphQL validation +* Query planning +* Schema introspection + +In order to avoid blocking threads that execute asynchronous code, +they are now run in a new thread pool with a priority queue. The size of the thread pool is based on the number of available CPU cores. + +The thread pool replaces the router's prior implementation that used Tokioโ€™s [`spawn_blocking`](https://docs.rs/tokio/latest/tokio/task/fn.spawn_blocking.html). + +`apollo.router.compute_jobs.queued` is a new gauge metric for the number of items in the thread pool's priority queue. + +> Note: when the native query planner is enabled, the dedicated queue of the legacy query planner is no longer used, so the `apollo.router.query_planning.queued` metric is no longer emitted. + +By [@SimonSapin](https://github.com/SimonSapin) in https://github.com/apollographql/router/pull/6247 diff --git a/.changesets/fix_tninesling_demand_control_variable_scoring.md b/.changesets/fix_tninesling_demand_control_variable_scoring.md new file mode 100644 index 0000000000..fdac861553 --- /dev/null +++ b/.changesets/fix_tninesling_demand_control_variable_scoring.md @@ -0,0 +1,41 @@ +### Fix demand control panic for custom scalars that represent non-GraphQL-compliant JSON ([PR #6288](https://github.com/apollographql/router/pull/6288)) + +Previously, a panic could be triggered in the router's demand control plugin with the following schema: + +``` +scalar ArbitraryJson + +type MyInput { + json: ArbitraryJson +} + +type Query { + fetch(args: MyInput): Int +} +``` + +Then, submitting the query + +``` +query FetchData($myJsonValue: ArbitraryJson) { + fetch(args: { + json: $myJsonValue + }) +} +``` + +and variables + +``` +{ + "myJsonValue": { + "field.with.dots": 1 + } +} +``` + +During scoring, the demand control plugin would attempt to convert the variable structure into a GraphQL-compliant structure requiring valid GraphQL names as keys. The dot characters in the keys however would cause a panic. + +With this fix, only the GraphQL compliant part of the input object is scored, and the arbitrary JSON marked by the custom scalar is scored as an opaque scalar (similar to how built-ins like `Int` or `String` are processed). + +By [@tninesling](https://github.com/tninesling) in https://github.com/apollographql/router/pull/6288 diff --git a/.changesets/fix_tninesling_remove_demand_control_warnings.md b/.changesets/fix_tninesling_remove_demand_control_warnings.md new file mode 100644 index 0000000000..195ad7d04c --- /dev/null +++ b/.changesets/fix_tninesling_remove_demand_control_warnings.md @@ -0,0 +1,5 @@ +### Remove noisy demand control logs ([PR #6192](https://github.com/apollographql/router/pull/6192)) + +Demand control no longer logs warnings when a subgraph response is missing a requested field. + +By [@tninesling](https://github.com/tninesling) in https://github.com/apollographql/router/pull/6192 diff --git a/.changesets/fix_tninesling_typename_resolution.md b/.changesets/fix_tninesling_typename_resolution.md new file mode 100644 index 0000000000..890cb13ff6 --- /dev/null +++ b/.changesets/fix_tninesling_typename_resolution.md @@ -0,0 +1,7 @@ +### Fix incorrect overriding of concrete type names with interface names when merging responses ([PR #6250](https://github.com/apollographql/router/pull/6250)) + +When using `@interfaceObject`, differing pieces of data can come back with either concrete types or interface types depending on the source. Previously, receiving the data in a particular order could incorrectly result in the interface name of a type overwriting its concrete name. + +To make the response merging order-agnostic, the router now checks the schema to ensure concrete types are not overwritten with interfaces or less specific types. + +By [@tninesling](https://github.com/tninesling) in https://github.com/apollographql/router/pull/6250 diff --git a/.changesets/maint_bnjjj_feat_854.md b/.changesets/maint_bnjjj_feat_854.md new file mode 100644 index 0000000000..2f5f7a762f --- /dev/null +++ b/.changesets/maint_bnjjj_feat_854.md @@ -0,0 +1,5 @@ +### Add entity caching invalidation configuration metrics ([PR #6286](https://github.com/apollographql/router/pull/6286)) + +We've added metrics for our analytics to know if entity caching invalidation is enabled. + +By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/6286 \ No newline at end of file diff --git a/.changesets/maint_bnjjj_fix_supergraph_events_span.md b/.changesets/maint_bnjjj_fix_supergraph_events_span.md new file mode 100644 index 0000000000..a0548cb374 --- /dev/null +++ b/.changesets/maint_bnjjj_fix_supergraph_events_span.md @@ -0,0 +1,5 @@ +### Avoid creating stub span for supergraph events if current span exists ([PR #6096](https://github.com/apollographql/router/pull/6096)) + +The router optimized its telemetry implementation by not creating a redundant span when it already has a span available to use the span's extensions for supergraph events. + +By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/6096 \ No newline at end of file diff --git a/.changesets/maint_geal_query_planner_cache_key_improvements.md b/.changesets/maint_geal_query_planner_cache_key_improvements.md new file mode 100644 index 0000000000..afb446115a --- /dev/null +++ b/.changesets/maint_geal_query_planner_cache_key_improvements.md @@ -0,0 +1,8 @@ +### Query planner cache key improvements ([Issue #5160](https://github.com/apollographql/router/issues/5160)) + +> [!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. + +Several performance improvements have been implemented for query plan cache key generation. In particular, the distributed cache's key format has changed, which adds prefixes to the different key segments to help in debugging. + +By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/6206 \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 2db933defe..bb4866bf62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,296 +4,6 @@ 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.58.0] - 2024-11-26 - -> [!IMPORTANT] -> If you have enabled [Distributed query plan caching](https://www.apollographql.com/docs/router/configuration/distributed-caching/#distributed-query-plan-caching), this release contains changes which necessarily alter 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. - -## ๐Ÿš€ Features - -### Support DNS resolution strategy configuration ([PR #6109](https://github.com/apollographql/router/pull/6109)) - -The router now supports a configurable DNS resolution strategy for the URLs of coprocessors and subgraphs. -The new option is called `dns_resolution_strategy` and supports the following values: -* `ipv4_only` - Only query for `A` (IPv4) records. -* `ipv6_only` - Only query for `AAAA` (IPv6) records. -* `ipv4_and_ipv6` - Query for both `A` (IPv4) and `AAAA` (IPv6) records in parallel. -* `ipv6_then_ipv4` - Query for `AAAA` (IPv6) records first; if that fails, query for `A` (IPv4) records. -* `ipv4_then_ipv6`(default) - Query for `A` (IPv4) records first; if that fails, query for `AAAA` (IPv6) records. - -You can change the DNS resolution strategy applied to a subgraph's URL: - -```yaml title="router.yaml" -traffic_shaping: - all: - dns_resolution_strategy: ipv4_then_ipv6 - -``` - -You can also change the DNS resolution strategy applied to a coprocessor's URL: - -```yaml title="router.yaml" -coprocessor: - url: http://coprocessor.example.com:8081 - client: - dns_resolution_strategy: ipv4_then_ipv6 - -``` - -By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6109 - -### Configuration options for HTTP/1 max headers and buffer limits ([PR #6194](https://github.com/apollographql/router/pull/6194)) - -This update introduces configuration options that allow you to adjust the maximum number of HTTP/1 request headers and the maximum buffer size allocated for headers. - -By default, the router accepts HTTP/1 requests with up to 100 headers and allocates ~400 KiB of buffer space to store them. If you need to handle requests with more headers or require a different buffer size, you can now configure these limits in the router's configuration file: -```yaml -limits: - http1_request_max_headers: 200 - http1_request_max_buf_size: 200kib -``` - -If you are using the router as a Rust crate, the `http1_request_max_buf_size` option requires the `hyper_header_limits` feature and also necessitates using Apollo's fork of the Hyper crate until the [changes are merged upstream](https://github.com/hyperium/hyper/pull/3523). -You can include this fork by adding the following patch to your Cargo.toml file: -```toml -[patch.crates-io] -"hyper" = { git = "https://github.com/apollographql/hyper.git", tag = "header-customizations-20241108" } -``` - -By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6194 - -### Compress subgraph operations by generating fragments ([PR #6013](https://github.com/apollographql/router/pull/6013)) - -The router now compresses operations sent to subgraphs by default by generating fragment -definitions and using them in the operation. - -This change enables `generate_query_fragments` by default while disabling `experimental_reuse_query_fragments`. When enabled, `experimental_reuse_query_fragments` attempts to intelligently reuse the fragment definitions -from the original operation. However, fragment generation with `generate_query_fragments` is much faster and produces better outputs in most cases. - -If you are relying on the shape of fragments in your subgraph operations or tests, you can opt out of the new algorithm with the configuration below. - -> Note: The subgraph operations generated by the query planner are not guaranteed consistent release over release. We strongly recommend against relying on the shape of planned subgraph operations, as new router features and optimizations will continuously affect it. We plan to remove `experimental_reuse_query_fragments` in a future release. - -```yaml -supergraph: - generate_query_fragments: false - experimental_reuse_query_fragments: true -``` - -By [@lrlna](https://github.com/lrlna) in https://github.com/apollographql/router/pull/6013 - -### Add subgraph request id ([PR #5858](https://github.com/apollographql/router/pull/5858)) - -The router now supports a subgraph request ID that is a unique string identifying a subgraph request and response. It allows plugins and coprocessors to keep some state per subgraph request by matching on this ID. It's available in coprocessors as `subgraphRequestId` and Rhai scripts as `request.subgraph.id` and `response.subgraph.id`. - - -By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/5858 - -### Add `extensions.service` for all subgraph errors ([PR #6191](https://github.com/apollographql/router/pull/6191)) - - -For improved debuggability, the router now supports adding a subgraph's name as an extension to all errors originating from the subgraph. - -If `include_subgraph_errors` is `true` for a particular subgraph, all errors originating in this subgraph will have the subgraph's name exposed as a `service` extension. - -You can enable subgraph errors with the following configuration: -```yaml title="router.yaml" -include_subgraph_errors: - all: true # Propagate errors from all subgraphs -``` -> Note: This option is enabled by default by the router's [dev mode](https://www.apollographql.com/docs/graphos/reference/router/configuration#dev-mode-defaults). - -Consequently, when a subgraph returns an error, it will have a `service` extension with the subgraph name as its value. The following example shows the extension for a `products` subgraph: - -```json -{ - "data": null, - "errors": [ - { - "message": "Invalid product ID", - "path": [], - "extensions": { - "service": "products" - } - } - ] -} -``` - -By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6191 - -### Add `@context` support in the native query planner ([PR #6310](https://github.com/apollographql/router/pull/6310)) - -The [`@context`](https://www.apollographql.com/docs/graphos/reference/federation/directives#context) feature is now available in the [native query planner](https://www.apollographql.com/docs/graphos/routing/query-planning/native-query-planner). -This brings the native query planner to feature parity with the legacy query planner for all Federation v2 graphs. The native query planner can be enabled with the following configuration: -```yaml, filename=router.yaml -experimental_query_planner_mode: new -``` - - -By [@clenfest](https://github.com/clenfest), [@TylerBloom](https://github.com/TylerBloom) in https://github.com/apollographql/router/pull/6310 - -## ๐Ÿ› Fixes - -### Remove noisy demand control logs ([PR #6192](https://github.com/apollographql/router/pull/6192)) - -Demand control no longer logs warnings when a subgraph response is missing a requested field. - -By [@tninesling](https://github.com/tninesling) in https://github.com/apollographql/router/pull/6192 - -### Renamed headers' original values can again be propagated ([PR #6281](https://github.com/apollographql/router/pull/6281)) - -[PR #4535](https://github.com/apollographql/router/pull/4535) introduced a regression where the following header propagation config would not work: - -```yaml -headers: -- propagate: - named: a - rename: b -- propagate: - named: a - rename: c -``` - -The goal of the original PR was to prevent multiple headers from being mapped to a single target header. However, it did not consider renames and instead prevented multiple mappings from the same source header. -The router now propagates headers properly and ensures that a target header is only propagated to once. - -By [@BrynCooke](https://github.com/BrynCooke) in https://github.com/apollographql/router/pull/6281 - -### Introspection response deduplication should always produce results ([Issue #6249](https://github.com/apollographql/router/issues/6249)) - -To reduce CPU usage, query planning and introspection queries are deduplicated. In some cases, deduplicated introspection queries were not receiving their result. This issue has been fixed, and the router now sends results in all cases. - -By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/6257 - -### Don't log response data upon notification failure for subgraph batching ([PR #6150](https://github.com/apollographql/router/pull/6150)) - -For a subgraph batching operation, the router now doesn't log the entire subgraph response when failing to notify a waiting batch participant. This saves the router from logging the large amount of data (PII and/or non-PII data) that a subgraph response may contain. - -By [@garypen](https://github.com/garypen) in https://github.com/apollographql/router/pull/6150 - -### Move heavy computation to a thread pool with a priority queue ([PR #6247](https://github.com/apollographql/router/pull/6247)) - -The router now avoids blocking threads when executing asynchronous code by using a thread pool with a priority queue. - -This improves the performance of the following components that can take non-trivial amounts of CPU time: - -* GraphQL parsing -* GraphQL validation -* Query planning -* Schema introspection - -The size of the thread pool is based on the number of available CPU cores. - -The thread pool replaces the router's prior implementation that used Tokioโ€™s [`spawn_blocking`](https://docs.rs/tokio/latest/tokio/task/fn.spawn_blocking.html). - -`apollo.router.compute_jobs.queued` is a new gauge metric for the number of items in the thread pool's priority queue. - -> Note: when the native query planner is enabled, the dedicated queue of the legacy query planner is no longer used, so the `apollo.router.query_planning.queued` metric is no longer emitted. - -By [@SimonSapin](https://github.com/SimonSapin) in https://github.com/apollographql/router/pull/6247 - -### Limit the amount of GraphQL validation errors returned per response ([PR #6187](https://github.com/apollographql/router/pull/6187)) - -When an invalid query is submitted, the router now returns at most one hundred GraphQL parsing and validation errors in a response. This prevents generating too large of a response for a nonsensical document. - -By [@goto-bus-stop](https://github.com/goto-bus-stop) in https://github.com/apollographql/router/pull/6187 - -### Remove placeholders from file upload query variables ([PR #6293](https://github.com/apollographql/router/pull/6293)) - -Previously, file upload query variables in subgraph requests incorrectly contained internal placeholders. -According to the [GraphQL Multipart Request Spec](https://github.com/jaydenseric/graphql-multipart-request-spec?tab=readme-ov-file#multipart-form-field-structure), these variables should be set to null. -This issue has been fixed by ensuring that the router complies with the specification and improving compatibility with subgraphs handling file uploads. - -By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6293 - -### Overhead processing metrics should exclude subgraph response time when deduplication is enabled ([PR #6207](https://github.com/apollographql/router/pull/6207)) - -The router's calculated overhead processing time has been fixed, where the time spent waiting for the subgraph response of a deduplicated request had been incorrectly included. - -By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/6207 - -### Fix demand control panic for custom scalars that represent non-GraphQL-compliant JSON ([PR #6288](https://github.com/apollographql/router/pull/6288)) - -Previously, a panic could be triggered in the router's demand control plugin with the following schema: - -``` -scalar ArbitraryJson - -type MyInput { - json: ArbitraryJson -} - -type Query { - fetch(args: MyInput): Int -} -``` - -Then, submitting the query - -``` -query FetchData(: ArbitraryJson) { - fetch(args: { - json: - }) -} -``` - -and variables - -``` -{ - "myJsonValue": { - "field.with.dots": 1 - } -} -``` - -During scoring, the demand control plugin would attempt to convert the variable structure into a GraphQL-compliant structure requiring valid GraphQL names as keys. The dot characters in the keys however would cause a panic. - -With this fix, only the GraphQL compliant part of the input object is scored, and the arbitrary JSON marked by the custom scalar is scored as an opaque scalar (similar to how built-ins like `Int` or `String` are processed). - -By [@tninesling](https://github.com/tninesling) in https://github.com/apollographql/router/pull/6288 - -### Fix incorrect overriding of concrete type names with interface names when merging responses ([PR #6250](https://github.com/apollographql/router/pull/6250)) - -When using `@interfaceObject`, differing pieces of data can come back with either concrete types or interface types depending on the source. Previously, receiving the data in a particular order could incorrectly result in the interface name of a type overwriting its concrete name. - -To make the response merging order-agnostic, the router now checks the schema to ensure concrete types are not overwritten with interfaces or less specific types. - -By [@tninesling](https://github.com/tninesling) in https://github.com/apollographql/router/pull/6250 - -## ๐Ÿ›  Maintenance - -### Query planner cache key improvements ([Issue #5160](https://github.com/apollographql/router/issues/5160)) - -Several performance improvements have been implemented for query plan cache key generation. In particular, the distributed cache's key format has changed, which adds prefixes to the different key segments to help in debugging. - -By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/6206 - -### Add entity caching invalidation configuration metrics ([PR #6286](https://github.com/apollographql/router/pull/6286)) - -We've added metrics for our analytics to know if entity caching invalidation is enabled. - -By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/6286 - -### Avoid creating stub span for supergraph events if current span exists ([PR #6096](https://github.com/apollographql/router/pull/6096)) - -The router optimized its telemetry implementation by not creating a redundant span when it already has a span available to use the span's extensions for supergraph events. - -By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/6096 - -## ๐Ÿ“š Documentation - -### Clarify docs for authorization directive composition ([PR #6216](https://github.com/apollographql/router/pull/6216)) - -The docs for [authorization directive composition](https://www.apollographql.com/docs/graphos/routing/security/authorization#composition-and-federation) have been clarified, including corrected code examples. - - -By [@Meschreiber](https://github.com/Meschreiber) in https://github.com/apollographql/router/pull/6216 - - - # [1.57.1] - 2024-10-31 ## ๐Ÿ› Fixes diff --git a/Cargo.lock b/Cargo.lock index 57a87514d6..34e2c836de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -178,7 +178,7 @@ dependencies = [ [[package]] name = "apollo-federation" -version = "1.58.0" +version = "1.58.0-rc.2" dependencies = [ "apollo-compiler", "derive_more", @@ -231,7 +231,7 @@ dependencies = [ [[package]] name = "apollo-router" -version = "1.58.0" +version = "1.58.0-rc.2" dependencies = [ "access-json", "ahash", @@ -399,7 +399,7 @@ dependencies = [ [[package]] name = "apollo-router-benchmarks" -version = "1.58.0" +version = "1.58.0-rc.2" dependencies = [ "apollo-parser", "apollo-router", @@ -415,7 +415,7 @@ dependencies = [ [[package]] name = "apollo-router-scaffold" -version = "1.58.0" +version = "1.58.0-rc.2" dependencies = [ "anyhow", "cargo-scaffold", diff --git a/apollo-federation/Cargo.toml b/apollo-federation/Cargo.toml index c0103f435e..e0e8b9150c 100644 --- a/apollo-federation/Cargo.toml +++ b/apollo-federation/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-federation" -version = "1.58.0" +version = "1.58.0-rc.2" 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 359391b4a7..34410cad70 100644 --- a/apollo-router-benchmarks/Cargo.toml +++ b/apollo-router-benchmarks/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router-benchmarks" -version = "1.58.0" +version = "1.58.0-rc.2" 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 8b68e56a12..105b1ce0bd 100644 --- a/apollo-router-scaffold/Cargo.toml +++ b/apollo-router-scaffold/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router-scaffold" -version = "1.58.0" +version = "1.58.0-rc.2" authors = ["Apollo Graph, Inc. "] edition = "2021" license = "Elastic-2.0" diff --git a/apollo-router-scaffold/templates/base/Cargo.template.toml b/apollo-router-scaffold/templates/base/Cargo.template.toml index 00b111b264..0a181f0008 100644 --- a/apollo-router-scaffold/templates/base/Cargo.template.toml +++ b/apollo-router-scaffold/templates/base/Cargo.template.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.58.0" +apollo-router = "1.58.0-rc.2" {{/if}} {{/if}} async-trait = "0.1.52" diff --git a/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml b/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml index db2a939c2a..e81afd56d8 100644 --- a/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml +++ b/apollo-router-scaffold/templates/base/xtask/Cargo.template.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.58.0" } +apollo-router-scaffold = { git = "https://github.com/apollographql/router.git", tag = "v1.58.0-rc.2" } {{/if}} {{/if}} anyhow = "1.0.58" diff --git a/apollo-router/Cargo.toml b/apollo-router/Cargo.toml index f2cedca917..ab3a737fd0 100644 --- a/apollo-router/Cargo.toml +++ b/apollo-router/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router" -version = "1.58.0" +version = "1.58.0-rc.2" authors = ["Apollo Graph, Inc. "] repository = "https://github.com/apollographql/router/" documentation = "https://docs.rs/apollo-router" @@ -66,7 +66,7 @@ features = ["docs_rs"] access-json = "0.1.0" anyhow = "1.0.86" apollo-compiler.workspace = true -apollo-federation = { path = "../apollo-federation", version = "=1.58.0" } +apollo-federation = { path = "../apollo-federation", version = "=1.58.0-rc.2" } 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 e69604eb8c..1f9bc33cb9 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.58.0 + image: ghcr.io/apollographql/router:v1.58.0-rc.2 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 8225d7799a..0a22a025e4 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.58.0 + image: ghcr.io/apollographql/router:v1.58.0-rc.2 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 a84a7f1fcf..d6230610f5 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.58.0 + image: ghcr.io/apollographql/router:v1.58.0-rc.2 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 51cf64fa63..7ff3a8b8f7 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.58.0 +version: 1.58.0-rc.2 # 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.58.0" +appVersion: "v1.58.0-rc.2" diff --git a/helm/chart/router/README.md b/helm/chart/router/README.md index c68ab5cd8b..15e2be484d 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.58.0](https://img.shields.io/badge/Version-1.58.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.58.0](https://img.shields.io/badge/AppVersion-v1.58.0-informational?style=flat-square) +![Version: 1.58.0-rc.2](https://img.shields.io/badge/Version-1.58.0--rc.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.58.0-rc.2](https://img.shields.io/badge/AppVersion-v1.58.0--rc.2-informational?style=flat-square) ## Prerequisites @@ -11,7 +11,7 @@ ## Get Repo Info ```console -helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0 +helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0-rc.2 ``` ## Install Chart @@ -19,7 +19,7 @@ helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0 **Important:** only helm3 is supported ```console -helm upgrade --install [RELEASE_NAME] oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0 --values my-values.yaml +helm upgrade --install [RELEASE_NAME] oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0-rc.2 --values my-values.yaml ``` _See [configuration](#configuration) below._ diff --git a/licenses.html b/licenses.html index 8d5e68ad9f..37ceccad5d 100644 --- a/licenses.html +++ b/licenses.html @@ -44,13 +44,13 @@

          Third Party Licenses

          Overview of licenses:

        • + +
        • +

          Apache License 2.0

          +

          Used by:

          + +
          +                                 Apache License
          +                           Version 2.0, January 2004
          +                        https://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
           
        • @@ -3009,6 +3197,7 @@

          Used by:

        • clap_builder
        • clap_derive
        • clap_lex
        • +
        • opentelemetry-proto
                                         Apache License
                                    Version 2.0, January 2004
        @@ -5523,6 +5712,7 @@ 

        Used by:

      • utf-8
      • utf8parse
      • wasm-streams
      • +
      • zerocopy
                                    Apache License
                               Version 2.0, January 2004
      @@ -8242,6 +8432,7 @@ 

      Used by:

    54. bytes-utils
    55. cc
    56. cfg-if
    57. +
    58. ci_info
    59. cmake
    60. concurrent-queue
    61. const-random
    62. @@ -8256,6 +8447,7 @@

      Used by:

    63. derive_arbitrary
    64. displaydoc
    65. either
    66. +
    67. envmnt
    68. equivalent
    69. event-listener
    70. fastrand
    71. @@ -8266,6 +8458,7 @@

      Used by:

    72. fnv
    73. form_urlencoded
    74. fraction
    75. +
    76. fsio
    77. futures-lite
    78. futures-timer
    79. gimli
    80. @@ -11064,6 +11257,53 @@

      Used by:

      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. +
      +
    81. +
    82. +

      Apache License 2.0

      +

      Used by:

      + +
      # Contributing
      +
      +## License
      +
      +Licensed under either of
      +
      + * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
      + * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
      +
      +at your option.
      +
      +### Contribution
      +
      +Unless you explicitly state otherwise, any contribution intentionally submitted
      +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
      +additional terms or conditions.
      +
      +
    83. +
    84. +

      Apache License 2.0

      +

      Used by:

      + +
      ../../LICENSE-APACHE
      +
    85. +
    86. +

      Apache License 2.0

      +

      Used by:

      + +
      // Licensed under the Apache License, Version 2.0
      +// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
      +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
      +// All files in the project carrying such notice may not be copied, modified, or distributed
      +// except according to those terms.
       
    87. @@ -11700,14 +11940,10 @@

      Used by:

      Apache License 2.0

      Used by:

        -
      • apollo-compiler
      • -
      • apollo-parser
      • -
      • apollo-smith
      • async-graphql-axum
      • async-graphql-derive
      • async-graphql-parser
      • async-graphql-value
      • -
      • buildstructor
      • deno-proc-macro-rules
      • deno-proc-macro-rules-macros
      • dunce
      • @@ -11723,7 +11959,6 @@

        Used by:

      • num-cmp
      • prost
      • rhai_codegen
      • -
      • serde_derive_default
      • siphasher
      • system-configuration
      • system-configuration-sys
      • @@ -11806,6 +12041,48 @@

        Used by:

        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:

        + +
        Copyright [2022] [Bryn Cooke]
        +
        +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:

        + +
        Copyright [2023] [Bryn Cooke]
        +
        +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.
        @@ -11828,6 +12105,33 @@ 

        Used by:

        at your option. All files in the project carrying such notice may not be copied, modified, or distributed except according to those terms. +
        +
      • +
      • +

        Apache License 2.0

        +

        Used by:

        + +
        MIT OR Apache-2.0
        +
      • +
      • +

        Apache License 2.0

        +

        Used by:

        + +
        MIT OR Apache-2.0
        +
        +
      • +
      • +

        Apache License 2.0

        +

        Used by:

        + +
        MIT or Apache-2.0
         
      • @@ -12390,6 +12694,9 @@

        Elastic License 2.0

        Used by:

        Copyright 2021 Apollo Graph, Inc.
         
        @@ -12654,36 +12961,6 @@ 

        Used by:

        // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -
        -
      • -
      • -

        ISC License

        -

        Used by:

        - -
        // Copyright 2021 Brian Smith.
        -//
        -// Permission to use, copy, modify, and/or distribute this software for any
        -// purpose with or without fee is hereby granted, provided that the above
        -// copyright notice and this permission notice appear in all copies.
        -//
        -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
        -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
        -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
        -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
        -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
        -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
        -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
        -
        -#[test]
        -fn cert_without_extensions_test() {
        -    // Check the certificate is valid with
        -    // `openssl x509 -in cert_without_extensions.der -inform DER -text -noout`
        -    const CERT_WITHOUT_EXTENSIONS_DER: &[u8] = include_bytes!("cert_without_extensions.der");
        -
        -    assert!(webpki::EndEntityCert::try_from(CERT_WITHOUT_EXTENSIONS_DER).is_ok());
        -}
         
      • @@ -12753,6 +13030,7 @@

        ISC License

        Used by:

        ISC License:
         
        @@ -13474,6 +13752,66 @@ 

        Used by:

        shall be included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. +
        +
      • +
      • +

        MIT License

        +

        Used by:

        + +
        Copyright (c) 2019 Carl Lerche
        +
        +Permission is hereby granted, free of charge, to any
        +person obtaining a copy of this software and associated
        +documentation files (the "Software"), to deal in the
        +Software without restriction, including without
        +limitation the rights to use, copy, modify, merge,
        +publish, distribute, sublicense, and/or sell copies of
        +the Software, and to permit persons to whom the Software
        +is furnished to do so, subject to the following
        +conditions:
        +
        +The above copyright notice and this permission notice
        +shall be included in all copies or substantial portions
        +of the Software.
        +
        +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
        +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
        +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
        +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
        +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
        +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
        +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
        +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
        +DEALINGS IN THE SOFTWARE.
        +
        +Copyright (c) 2018 David Tolnay
        +
        +Permission is hereby granted, free of charge, to any
        +person obtaining a copy of this software and associated
        +documentation files (the "Software"), to deal in the
        +Software without restriction, including without
        +limitation the rights to use, copy, modify, merge,
        +publish, distribute, sublicense, and/or sell copies of
        +the Software, and to permit persons to whom the Software
        +is furnished to do so, subject to the following
        +conditions:
        +
        +The above copyright notice and this permission notice
        +shall be included in all copies or substantial portions
        +of the Software.
        +
         THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
         ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
         TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
        @@ -14480,8 +14818,6 @@ 

        Used by:

        MIT License

        Used by:

          -
        • async-stream
        • -
        • async-stream-impl
        • base64-simd
        • convert_case
        • cookie-factory
        • @@ -14824,6 +15160,8 @@

          Used by:

          The MIT License (MIT)
           
          @@ -15322,7 +15660,14 @@ 

          Used by:

          MIT License

          Used by:

          This project is dual-licensed under the Unlicense and MIT licenses.
           
          @@ -15724,7 +16069,6 @@ 

          Used by:

          Mozilla Public License 2.0

          Used by:

          Mozilla Public License Version 2.0
          @@ -16107,8 +16451,8 @@ 

          Used by:

          Mozilla Public License 2.0

          Used by:

          Mozilla Public License Version 2.0
           ==================================
          @@ -16483,6 +16827,35 @@ 

          Used by:

          This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. +
          + +
        • +

          Mozilla Public License 2.0

          +

          Used by:

          + +
          This packge contains a modified version of ca-bundle.crt:
          +
          +ca-bundle.crt -- Bundle of CA Root Certificates
          +
          +Certificate data from Mozilla as of: Thu Nov  3 19:04:19 2011#
          +This is a bundle of X.509 certificates of public Certificate Authorities
          +(CA). These were automatically extracted from Mozilla's root certificates
          +file (certdata.txt).  This file can be found in the mozilla source tree:
          +http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt?raw=1#
          +It contains the certificates in PEM format and therefore
          +can be directly used with curl / libcurl / php_curl, or with
          +an Apache+mod_ssl webserver for SSL client authentication.
          +Just configure this file as the SSLCACertificateFile.#
          +
          +***** BEGIN LICENSE BLOCK *****
          +This Source Code Form is subject to the terms of the Mozilla Public License,
          +v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain
          +one at http://mozilla.org/MPL/2.0/.
          +
          +***** END LICENSE BLOCK *****
          +@(#) $RCSfile: certdata.txt,v $ $Revision: 1.80 $ $Date: 2011/11/03 15:11:58 $
           
        • diff --git a/scripts/install.sh b/scripts/install.sh index 6446019f5b..a1b50a9ae3 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.58.0" +PACKAGE_VERSION="v1.58.0-rc.2" download_binary() { downloader --check From 16eed65a3ae8426526d5ef7c8202434c7fbf9a14 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Wed, 27 Nov 2024 17:16:19 +0200 Subject: [PATCH 76/77] prep release: v1.58.0-rc.3 --- Cargo.lock | 8 ++++---- apollo-federation/Cargo.toml | 2 +- apollo-router-benchmarks/Cargo.toml | 2 +- apollo-router-scaffold/Cargo.toml | 2 +- apollo-router-scaffold/templates/base/Cargo.template.toml | 2 +- .../templates/base/xtask/Cargo.template.toml | 2 +- apollo-router/Cargo.toml | 4 ++-- dockerfiles/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 | 6 +++--- licenses.html | 5 +---- scripts/install.sh | 2 +- 14 files changed, 21 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 34e2c836de..c9180eda83 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -178,7 +178,7 @@ dependencies = [ [[package]] name = "apollo-federation" -version = "1.58.0-rc.2" +version = "1.58.0-rc.3" dependencies = [ "apollo-compiler", "derive_more", @@ -231,7 +231,7 @@ dependencies = [ [[package]] name = "apollo-router" -version = "1.58.0-rc.2" +version = "1.58.0-rc.3" dependencies = [ "access-json", "ahash", @@ -399,7 +399,7 @@ dependencies = [ [[package]] name = "apollo-router-benchmarks" -version = "1.58.0-rc.2" +version = "1.58.0-rc.3" dependencies = [ "apollo-parser", "apollo-router", @@ -415,7 +415,7 @@ dependencies = [ [[package]] name = "apollo-router-scaffold" -version = "1.58.0-rc.2" +version = "1.58.0-rc.3" dependencies = [ "anyhow", "cargo-scaffold", diff --git a/apollo-federation/Cargo.toml b/apollo-federation/Cargo.toml index e0e8b9150c..716dd01f6b 100644 --- a/apollo-federation/Cargo.toml +++ b/apollo-federation/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-federation" -version = "1.58.0-rc.2" +version = "1.58.0-rc.3" 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 34410cad70..097a7501df 100644 --- a/apollo-router-benchmarks/Cargo.toml +++ b/apollo-router-benchmarks/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router-benchmarks" -version = "1.58.0-rc.2" +version = "1.58.0-rc.3" 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 105b1ce0bd..ca32fb0d3d 100644 --- a/apollo-router-scaffold/Cargo.toml +++ b/apollo-router-scaffold/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router-scaffold" -version = "1.58.0-rc.2" +version = "1.58.0-rc.3" authors = ["Apollo Graph, Inc. "] edition = "2021" license = "Elastic-2.0" diff --git a/apollo-router-scaffold/templates/base/Cargo.template.toml b/apollo-router-scaffold/templates/base/Cargo.template.toml index 0a181f0008..162f4f70b9 100644 --- a/apollo-router-scaffold/templates/base/Cargo.template.toml +++ b/apollo-router-scaffold/templates/base/Cargo.template.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.58.0-rc.2" +apollo-router = "1.58.0-rc.3" {{/if}} {{/if}} async-trait = "0.1.52" diff --git a/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml b/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml index e81afd56d8..6f29bfeaff 100644 --- a/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml +++ b/apollo-router-scaffold/templates/base/xtask/Cargo.template.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.58.0-rc.2" } +apollo-router-scaffold = { git = "https://github.com/apollographql/router.git", tag = "v1.58.0-rc.3" } {{/if}} {{/if}} anyhow = "1.0.58" diff --git a/apollo-router/Cargo.toml b/apollo-router/Cargo.toml index ab3a737fd0..2b2e904f0c 100644 --- a/apollo-router/Cargo.toml +++ b/apollo-router/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "apollo-router" -version = "1.58.0-rc.2" +version = "1.58.0-rc.3" authors = ["Apollo Graph, Inc. "] repository = "https://github.com/apollographql/router/" documentation = "https://docs.rs/apollo-router" @@ -66,7 +66,7 @@ features = ["docs_rs"] access-json = "0.1.0" anyhow = "1.0.86" apollo-compiler.workspace = true -apollo-federation = { path = "../apollo-federation", version = "=1.58.0-rc.2" } +apollo-federation = { path = "../apollo-federation", version = "=1.58.0-rc.3" } 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 1f9bc33cb9..c982ce6391 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.58.0-rc.2 + image: ghcr.io/apollographql/router:v1.58.0-rc.3 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 0a22a025e4..f5a87af6ab 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.58.0-rc.2 + image: ghcr.io/apollographql/router:v1.58.0-rc.3 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 d6230610f5..9fe89d4aae 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.58.0-rc.2 + image: ghcr.io/apollographql/router:v1.58.0-rc.3 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 7ff3a8b8f7..013cdd9cc7 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.58.0-rc.2 +version: 1.58.0-rc.3 # 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.58.0-rc.2" +appVersion: "v1.58.0-rc.3" diff --git a/helm/chart/router/README.md b/helm/chart/router/README.md index 15e2be484d..7db9fcec88 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.58.0-rc.2](https://img.shields.io/badge/Version-1.58.0--rc.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.58.0-rc.2](https://img.shields.io/badge/AppVersion-v1.58.0--rc.2-informational?style=flat-square) +![Version: 1.58.0-rc.3](https://img.shields.io/badge/Version-1.58.0--rc.3-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.58.0-rc.3](https://img.shields.io/badge/AppVersion-v1.58.0--rc.3-informational?style=flat-square) ## Prerequisites @@ -11,7 +11,7 @@ ## Get Repo Info ```console -helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0-rc.2 +helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0-rc.3 ``` ## Install Chart @@ -19,7 +19,7 @@ helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0-rc.2 **Important:** only helm3 is supported ```console -helm upgrade --install [RELEASE_NAME] oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0-rc.2 --values my-values.yaml +helm upgrade --install [RELEASE_NAME] oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0-rc.3 --values my-values.yaml ``` _See [configuration](#configuration) below._ diff --git a/licenses.html b/licenses.html index 37ceccad5d..a2a75adc9c 100644 --- a/licenses.html +++ b/licenses.html @@ -48,9 +48,9 @@

          Overview of licenses:

        • MIT License (154)
        • BSD 3-Clause "New" or "Revised" License (11)
        • ISC License (8)
        • -
        • Elastic License 2.0 (6)
        • Mozilla Public License 2.0 (5)
        • BSD 2-Clause "Simplified" License (4)
        • +
        • Elastic License 2.0 (3)
        • Creative Commons Zero v1.0 Universal (2)
        • OpenSSL License (1)
        • Unicode License Agreement - Data Files and Software (2016) (1)
        • @@ -12694,9 +12694,6 @@

          Elastic License 2.0

          Used by:

          Copyright 2021 Apollo Graph, Inc.
           
          diff --git a/scripts/install.sh b/scripts/install.sh
          index a1b50a9ae3..80c5beed67 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.58.0-rc.2"
          +PACKAGE_VERSION="v1.58.0-rc.3"
           
           download_binary() {
               downloader --check
          
          From bff45b3be07c7f65c93ede05e2db11071ea851c1 Mon Sep 17 00:00:00 2001
          From: Jesse Rosenberger 
          Date: Wed, 27 Nov 2024 18:21:49 +0200
          Subject: [PATCH 77/77] prep release: v1.58.0
          
          Also includes re-applying changelog editorial from
          https://github.com/apollographql/router/pull/6331.
          ---
           ...ify_authorization_directive_composition.md |   6 -
           .../feat_add_dns_resolution_strategy.md       |  30 --
           .changesets/feat_error_extensions_service.md  |  32 --
           .changesets/feat_geal_subgraph_request_id.md  |   6 -
           ...ble_generate_query_fragments_by_default.md |  19 --
           .changesets/feat_max_headers.md               |  19 --
           .../feat_router_528_impl_set_context.md       |   6 -
           .../fix_bryn_fix_header_propagation.md        |  18 --
           ...ix_fix_file_upload_variable_placeholder.md |   7 -
           ...en_log_less_error_for_subgraph_batching.md |   5 -
           .../fix_geal_deduplication_processing_time.md |   5 -
           .../fix_geal_introspection_dedup_fix.md       |   5 -
           .changesets/fix_renee_limit_errors.md         |   5 -
           .changesets/fix_simon_compute_jobs.md         |  21 --
           ...nesling_demand_control_variable_scoring.md |  41 ---
           ...inesling_remove_demand_control_warnings.md |   5 -
           .../fix_tninesling_typename_resolution.md     |   7 -
           .changesets/maint_bnjjj_feat_854.md           |   5 -
           .../maint_bnjjj_fix_supergraph_events_span.md |   5 -
           ...al_query_planner_cache_key_improvements.md |   8 -
           CHANGELOG.md                                  | 290 ++++++++++++++++++
           Cargo.lock                                    |   8 +-
           apollo-federation/Cargo.toml                  |   2 +-
           apollo-router-benchmarks/Cargo.toml           |   2 +-
           apollo-router-scaffold/Cargo.toml             |   2 +-
           .../templates/base/Cargo.template.toml        |   2 +-
           .../templates/base/xtask/Cargo.template.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                   |   6 +-
           licenses.html                                 |   5 +-
           scripts/install.sh                            |   2 +-
           35 files changed, 314 insertions(+), 276 deletions(-)
           delete mode 100644 .changesets/docs_clarify_authorization_directive_composition.md
           delete mode 100644 .changesets/feat_add_dns_resolution_strategy.md
           delete mode 100644 .changesets/feat_error_extensions_service.md
           delete mode 100644 .changesets/feat_geal_subgraph_request_id.md
           delete mode 100644 .changesets/feat_lrlna_enable_generate_query_fragments_by_default.md
           delete mode 100644 .changesets/feat_max_headers.md
           delete mode 100644 .changesets/feat_router_528_impl_set_context.md
           delete mode 100644 .changesets/fix_bryn_fix_header_propagation.md
           delete mode 100644 .changesets/fix_fix_file_upload_variable_placeholder.md
           delete mode 100644 .changesets/fix_garypen_log_less_error_for_subgraph_batching.md
           delete mode 100644 .changesets/fix_geal_deduplication_processing_time.md
           delete mode 100644 .changesets/fix_geal_introspection_dedup_fix.md
           delete mode 100644 .changesets/fix_renee_limit_errors.md
           delete mode 100644 .changesets/fix_simon_compute_jobs.md
           delete mode 100644 .changesets/fix_tninesling_demand_control_variable_scoring.md
           delete mode 100644 .changesets/fix_tninesling_remove_demand_control_warnings.md
           delete mode 100644 .changesets/fix_tninesling_typename_resolution.md
           delete mode 100644 .changesets/maint_bnjjj_feat_854.md
           delete mode 100644 .changesets/maint_bnjjj_fix_supergraph_events_span.md
           delete mode 100644 .changesets/maint_geal_query_planner_cache_key_improvements.md
          
          diff --git a/.changesets/docs_clarify_authorization_directive_composition.md b/.changesets/docs_clarify_authorization_directive_composition.md
          deleted file mode 100644
          index 5413e0234e..0000000000
          --- a/.changesets/docs_clarify_authorization_directive_composition.md
          +++ /dev/null
          @@ -1,6 +0,0 @@
          -### Clarify docs for authorization directive composition ([PR #6216](https://github.com/apollographql/router/pull/6216))
          -
          -The docs for [authorization directive composition](https://www.apollographql.com/docs/graphos/routing/security/authorization#composition-and-federation) have been clarified, including corrected code examples.
          -
          -
          -By [@Meschreiber](https://github.com/Meschreiber) in https://github.com/apollographql/router/pull/6216
          diff --git a/.changesets/feat_add_dns_resolution_strategy.md b/.changesets/feat_add_dns_resolution_strategy.md
          deleted file mode 100644
          index 399865ced1..0000000000
          --- a/.changesets/feat_add_dns_resolution_strategy.md
          +++ /dev/null
          @@ -1,30 +0,0 @@
          -### Support DNS resolution strategy configuration ([PR #6109](https://github.com/apollographql/router/pull/6109))
          -
          -The router now supports a configurable DNS resolution strategy for the URLs of coprocessors and subgraphs.
          -The new option is called `dns_resolution_strategy` and supports the following values:
          -* `ipv4_only` - Only query for `A` (IPv4) records.
          -* `ipv6_only` - Only query for `AAAA` (IPv6) records.
          -* `ipv4_and_ipv6` - Query for both `A` (IPv4) and `AAAA` (IPv6) records in parallel.
          -* `ipv6_then_ipv4` - Query for `AAAA` (IPv6) records first; if that fails, query for `A` (IPv4) records.
          -* `ipv4_then_ipv6`(default) - Query for `A` (IPv4) records first; if that fails, query for `AAAA` (IPv6) records.
          -
          -You can change the DNS resolution strategy applied to a subgraph's URL:
          -
          -```yaml title="router.yaml"
          -traffic_shaping:
          -  all:
          -    dns_resolution_strategy: ipv4_then_ipv6
          -
          -```
          -
          -You can also change the DNS resolution strategy applied to a coprocessor's URL:
          -
          -```yaml title="router.yaml"
          -coprocessor:
          -  url: http://coprocessor.example.com:8081
          -  client:
          -    dns_resolution_strategy: ipv4_then_ipv6
          -
          -```
          -
          -By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6109
          diff --git a/.changesets/feat_error_extensions_service.md b/.changesets/feat_error_extensions_service.md
          deleted file mode 100644
          index e8a1e09031..0000000000
          --- a/.changesets/feat_error_extensions_service.md
          +++ /dev/null
          @@ -1,32 +0,0 @@
          -### Add `extensions.service` for all subgraph errors ([PR #6191](https://github.com/apollographql/router/pull/6191))
          -
          -
          -For improved debuggability, the router now supports adding a subgraph's name as an extension to all errors originating from the subgraph.
          -
          -If `include_subgraph_errors` is `true` for a particular subgraph, all errors originating in this subgraph will have the subgraph's name exposed as a `service` extension.
          -
          -You can enable subgraph errors with the following configuration:
          -```yaml title="router.yaml"
          -include_subgraph_errors:
          -  all: true # Propagate errors from all subgraphs
          -```
          -> Note: This option is enabled by default by the router's [dev mode](https://www.apollographql.com/docs/graphos/reference/router/configuration#dev-mode-defaults).
          -
          -Consequently, when a subgraph returns an error, it will have a `service` extension with the subgraph name as its value. The following example shows the extension for a `products` subgraph:
          -
          -```json
          -{
          -  "data": null,
          -  "errors": [
          -    {
          -      "message": "Invalid product ID",
          -      "path": [],
          -      "extensions": {
          -        "service": "products"
          -      }
          -    }
          -  ]
          -}
          -```
          -
          -By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6191
          \ No newline at end of file
          diff --git a/.changesets/feat_geal_subgraph_request_id.md b/.changesets/feat_geal_subgraph_request_id.md
          deleted file mode 100644
          index 07d85f8efd..0000000000
          --- a/.changesets/feat_geal_subgraph_request_id.md
          +++ /dev/null
          @@ -1,6 +0,0 @@
          -### Add subgraph request id ([PR #5858](https://github.com/apollographql/router/pull/5858))
          -
          -The router now supports a subgraph request ID that is a unique string identifying a subgraph request and response. It allows plugins and coprocessors to keep some state per subgraph request by matching on this ID. It's available in coprocessors as `subgraphRequestId` and Rhai scripts as `request.subgraph.id` and `response.subgraph.id`.
          -
          -
          -By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/5858
          \ No newline at end of file
          diff --git a/.changesets/feat_lrlna_enable_generate_query_fragments_by_default.md b/.changesets/feat_lrlna_enable_generate_query_fragments_by_default.md
          deleted file mode 100644
          index d541706cd9..0000000000
          --- a/.changesets/feat_lrlna_enable_generate_query_fragments_by_default.md
          +++ /dev/null
          @@ -1,19 +0,0 @@
          -### Compress subgraph operations by generating fragments ([PR #6013](https://github.com/apollographql/router/pull/6013))
          -
          -The router now compresses operations sent to subgraphs by default by generating fragment
          -definitions and using them in the operation.
          -
          -This change enables `generate_query_fragments` by default while disabling `experimental_reuse_query_fragments`. When enabled, `experimental_reuse_query_fragments` attempts to intelligently reuse the fragment definitions
          -from the original operation. However, fragment generation with `generate_query_fragments` is much faster also produces better outputs in most cases.
          -
          -If you are relying on the shape of fragments in your subgraph operations or tests, you can opt out of the new algorithm with the configuration below. 
          -
          -> Note: The subgraph operations generated by the query planner are not guaranteed consistent release over release. We strongly recommend against relying on the shape of planned subgraph operations, as new router features and optimizations will continuously affect it. We plan to remove `experimental_reuse_query_fragments` in a future release.
          -
          -```yaml
          -supergraph:
          -  generate_query_fragments: false
          -  experimental_reuse_query_fragments: true
          -```
          -
          -By [@lrlna](https://github.com/lrlna) in https://github.com/apollographql/router/pull/6013
          diff --git a/.changesets/feat_max_headers.md b/.changesets/feat_max_headers.md
          deleted file mode 100644
          index 97c58995a7..0000000000
          --- a/.changesets/feat_max_headers.md
          +++ /dev/null
          @@ -1,19 +0,0 @@
          -### Configuration options for HTTP/1 max headers and buffer limits ([PR #6194](https://github.com/apollographql/router/pull/6194))
          -
          -This update introduces configuration options that allow you to adjust the maximum number of HTTP/1 request headers and the maximum buffer size allocated for headers.
          -
          -By default, the router accepts HTTP/1 requests with up to 100 headers and allocates ~400 KiB of buffer space to store them. If you need to handle requests with more headers or require a different buffer size, you can now configure these limits in the router's configuration file:
          -```yaml
          -limits:
          -  http1_request_max_headers: 200
          -  http1_request_max_buf_size: 200kib
          -```
          -
          -If you are using the router as a Rust crate, the `http1_request_max_buf_size` option requires the `hyper_header_limits` feature and also necessitates using Apollo's fork of the Hyper crate until the [changes are merged upstream](https://github.com/hyperium/hyper/pull/3523).
          -You can include this fork by adding the following patch to your Cargo.toml file:
          -```toml
          -[patch.crates-io]
          -"hyper" = { git = "https://github.com/apollographql/hyper.git", tag = "header-customizations-20241108" }
          -```
          -
          -By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6194
          diff --git a/.changesets/feat_router_528_impl_set_context.md b/.changesets/feat_router_528_impl_set_context.md
          deleted file mode 100644
          index b805deca59..0000000000
          --- a/.changesets/feat_router_528_impl_set_context.md
          +++ /dev/null
          @@ -1,6 +0,0 @@
          -### Add `@context` support in the native query planner ([PR #6310](https://github.com/apollographql/router/pull/6310))
          -
          -The [`@context`](https://www.apollographql.com/docs/graphos/reference/federation/directives#context) feature is now available in the native query planner.
          -This brings the native query planner to feature parity with the legacy query planner for all Federation v2 graphs.
          -
          -By [@clenfest](https://github.com/clenfest), [@TylerBloom](https://github.com/TylerBloom) in https://github.com/apollographql/router/pull/6310
          \ No newline at end of file
          diff --git a/.changesets/fix_bryn_fix_header_propagation.md b/.changesets/fix_bryn_fix_header_propagation.md
          deleted file mode 100644
          index fe402a26c6..0000000000
          --- a/.changesets/fix_bryn_fix_header_propagation.md
          +++ /dev/null
          @@ -1,18 +0,0 @@
          -### Renamed headers' original values can again be propagated ([PR #6281](https://github.com/apollographql/router/pull/6281))
          -
          -[PR #4535](https://github.com/apollographql/router/pull/4535) introduced a regression where the following header propagation config would not work:
          -
          -```yaml
          -headers:
          -- propagate:
          -    named: a
          -    rename: b
          -- propagate:
          -    named: a
          -    rename: c
          -```
          -
          -The goal of the original PR was to prevent multiple headers from being mapped to a single target header. However, it did not consider renames and instead prevented multiple mappings from the same source header. 
          -The router now propagates headers properly and ensures that a target header is only propagated to once.
          -
          -By [@BrynCooke](https://github.com/BrynCooke) in https://github.com/apollographql/router/pull/6281
          diff --git a/.changesets/fix_fix_file_upload_variable_placeholder.md b/.changesets/fix_fix_file_upload_variable_placeholder.md
          deleted file mode 100644
          index 2e7dc5a521..0000000000
          --- a/.changesets/fix_fix_file_upload_variable_placeholder.md
          +++ /dev/null
          @@ -1,7 +0,0 @@
          -### Remove placeholders from file upload query variables ([PR #6293](https://github.com/apollographql/router/pull/6293))
          -
          -Previously, file upload query variables in subgraph requests incorrectly contained internal placeholders.
          -According to the [GraphQL Multipart Request Spec](https://github.com/jaydenseric/graphql-multipart-request-spec?tab=readme-ov-file#multipart-form-field-structure), these variables should be set to null.
          -This issue has been fixed by ensuring that the router complies with the specification and improving compatibility with subgraphs handling file uploads.
          -
          -By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6293
          diff --git a/.changesets/fix_garypen_log_less_error_for_subgraph_batching.md b/.changesets/fix_garypen_log_less_error_for_subgraph_batching.md
          deleted file mode 100644
          index 9f7d8d1628..0000000000
          --- a/.changesets/fix_garypen_log_less_error_for_subgraph_batching.md
          +++ /dev/null
          @@ -1,5 +0,0 @@
          -### Don't log response data upon notification failure for subgraph batching ([PR #6150](https://github.com/apollographql/router/pull/6150))
          -
          -For a subgraph batching operation, the router now doesn't log the entire subgraph response when failing to notify a waiting batch participant. This saves the router from logging the large amount of data (PII and/or non-PII data) that a subgraph response may contain.
          -
          -By [@garypen](https://github.com/garypen) in https://github.com/apollographql/router/pull/6150
          \ No newline at end of file
          diff --git a/.changesets/fix_geal_deduplication_processing_time.md b/.changesets/fix_geal_deduplication_processing_time.md
          deleted file mode 100644
          index 71e10b87ed..0000000000
          --- a/.changesets/fix_geal_deduplication_processing_time.md
          +++ /dev/null
          @@ -1,5 +0,0 @@
          -### Overhead processing metrics should exclude subgraph response time when deduplication is enabled ([PR #6207](https://github.com/apollographql/router/pull/6207))
          -
          -The router's calculated overhead processing time has been fixed, where the time spent waiting for the subgraph response of a deduplicated request had been incorrectly included.
          -
          -By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/6207
          \ No newline at end of file
          diff --git a/.changesets/fix_geal_introspection_dedup_fix.md b/.changesets/fix_geal_introspection_dedup_fix.md
          deleted file mode 100644
          index 3fc10a3748..0000000000
          --- a/.changesets/fix_geal_introspection_dedup_fix.md
          +++ /dev/null
          @@ -1,5 +0,0 @@
          -### Introspection response deduplication should always produce results ([Issue #6249](https://github.com/apollographql/router/issues/6249))
          -
          -To reduce CPU usage, query planning and introspection queries are deduplicated. In some cases, deduplicated introspection queries were not receiving their result. This issue has been fixed, and the router now sends results in all cases.
          -
          -By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/6257
          \ No newline at end of file
          diff --git a/.changesets/fix_renee_limit_errors.md b/.changesets/fix_renee_limit_errors.md
          deleted file mode 100644
          index c2df146205..0000000000
          --- a/.changesets/fix_renee_limit_errors.md
          +++ /dev/null
          @@ -1,5 +0,0 @@
          -### Limit the amount of GraphQL validation errors returned per response ([PR #6187](https://github.com/apollographql/router/pull/6187))
          -
          -When an invalid query is submitted, the router now returns at most one hundred GraphQL parsing and validation errors in a response. This prevents generating too large of a response for a nonsensical document.
          -
          -By [@goto-bus-stop](https://github.com/goto-bus-stop) in https://github.com/apollographql/router/pull/6187
          \ No newline at end of file
          diff --git a/.changesets/fix_simon_compute_jobs.md b/.changesets/fix_simon_compute_jobs.md
          deleted file mode 100644
          index ac7f1fccaa..0000000000
          --- a/.changesets/fix_simon_compute_jobs.md
          +++ /dev/null
          @@ -1,21 +0,0 @@
          -### Move heavy computation to a thread pool with a priority queue ([PR #6247](https://github.com/apollographql/router/pull/6247))
          -
          -The router now avoids blocking threads when executing asynchronous code by using a thread pool with a priority queue.
          -
          -This improves the performance of the following components can take non-trivial amounts of CPU time:
          -
          -* GraphQL parsing
          -* GraphQL validation
          -* Query planning
          -* Schema introspection
          -
          -In order to avoid blocking threads that execute asynchronous code,
          -they are now run in a new thread pool with a priority queue. The size of the thread pool is based on the number of available CPU cores.
          -
          -The thread pool replaces the router's prior implementation that used Tokioโ€™s [`spawn_blocking`](https://docs.rs/tokio/latest/tokio/task/fn.spawn_blocking.html).
          -
          -`apollo.router.compute_jobs.queued` is a new gauge metric for the number of items in the thread pool's priority queue. 
          -
          -> Note: when the native query planner is enabled, the dedicated queue of the legacy query planner is no longer used, so the `apollo.router.query_planning.queued` metric is no longer emitted.
          -
          -By [@SimonSapin](https://github.com/SimonSapin) in https://github.com/apollographql/router/pull/6247
          diff --git a/.changesets/fix_tninesling_demand_control_variable_scoring.md b/.changesets/fix_tninesling_demand_control_variable_scoring.md
          deleted file mode 100644
          index fdac861553..0000000000
          --- a/.changesets/fix_tninesling_demand_control_variable_scoring.md
          +++ /dev/null
          @@ -1,41 +0,0 @@
          -### Fix demand control panic for custom scalars that represent non-GraphQL-compliant JSON ([PR #6288](https://github.com/apollographql/router/pull/6288))
          -
          -Previously, a panic could be triggered in the router's demand control plugin with the following schema:
          -
          -```
          -scalar ArbitraryJson
          -
          -type MyInput {
          -    json: ArbitraryJson
          -}
          -
          -type Query {
          -    fetch(args: MyInput): Int
          -}
          -```
          -
          -Then, submitting the query
          -
          -```
          -query FetchData($myJsonValue: ArbitraryJson) {
          -    fetch(args: {
          -        json: $myJsonValue
          -    })
          -}
          -```
          -
          -and variables
          -
          -```
          -{
          -    "myJsonValue": {
          -        "field.with.dots": 1
          -    }
          -}
          -```
          -
          -During scoring, the demand control plugin would attempt to convert the variable structure into a GraphQL-compliant structure requiring valid GraphQL names as keys. The dot characters in the keys however would cause a panic. 
          -
          -With this fix, only the GraphQL compliant part of the input object is scored, and the arbitrary JSON marked by the custom scalar is scored as an opaque scalar (similar to how built-ins like `Int` or `String` are processed).
          -
          -By [@tninesling](https://github.com/tninesling) in https://github.com/apollographql/router/pull/6288
          diff --git a/.changesets/fix_tninesling_remove_demand_control_warnings.md b/.changesets/fix_tninesling_remove_demand_control_warnings.md
          deleted file mode 100644
          index 195ad7d04c..0000000000
          --- a/.changesets/fix_tninesling_remove_demand_control_warnings.md
          +++ /dev/null
          @@ -1,5 +0,0 @@
          -### Remove noisy demand control logs ([PR #6192](https://github.com/apollographql/router/pull/6192))
          -
          -Demand control no longer logs warnings when a subgraph response is missing a requested field.
          -
          -By [@tninesling](https://github.com/tninesling) in https://github.com/apollographql/router/pull/6192
          diff --git a/.changesets/fix_tninesling_typename_resolution.md b/.changesets/fix_tninesling_typename_resolution.md
          deleted file mode 100644
          index 890cb13ff6..0000000000
          --- a/.changesets/fix_tninesling_typename_resolution.md
          +++ /dev/null
          @@ -1,7 +0,0 @@
          -### Fix incorrect overriding of concrete type names with interface names when merging responses ([PR #6250](https://github.com/apollographql/router/pull/6250))
          -
          -When using `@interfaceObject`, differing pieces of data can come back with either concrete types or interface types depending on the source. Previously, receiving the data in a particular order could incorrectly result in the interface name of a type overwriting its concrete name.
          -
          -To make the response merging order-agnostic, the router now checks the schema to ensure concrete types are not overwritten with interfaces or less specific types.
          -
          -By [@tninesling](https://github.com/tninesling) in https://github.com/apollographql/router/pull/6250
          diff --git a/.changesets/maint_bnjjj_feat_854.md b/.changesets/maint_bnjjj_feat_854.md
          deleted file mode 100644
          index 2f5f7a762f..0000000000
          --- a/.changesets/maint_bnjjj_feat_854.md
          +++ /dev/null
          @@ -1,5 +0,0 @@
          -### Add entity caching invalidation configuration metrics ([PR #6286](https://github.com/apollographql/router/pull/6286))
          -
          -We've added metrics for our analytics to know if entity caching invalidation is enabled.
          -
          -By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/6286
          \ No newline at end of file
          diff --git a/.changesets/maint_bnjjj_fix_supergraph_events_span.md b/.changesets/maint_bnjjj_fix_supergraph_events_span.md
          deleted file mode 100644
          index a0548cb374..0000000000
          --- a/.changesets/maint_bnjjj_fix_supergraph_events_span.md
          +++ /dev/null
          @@ -1,5 +0,0 @@
          -### Avoid creating stub span for supergraph events if current span exists ([PR #6096](https://github.com/apollographql/router/pull/6096))
          -
          -The router optimized its telemetry implementation by not creating a redundant span when it already has a span available to use the span's extensions for supergraph events.
          -
          -By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/6096
          \ No newline at end of file
          diff --git a/.changesets/maint_geal_query_planner_cache_key_improvements.md b/.changesets/maint_geal_query_planner_cache_key_improvements.md
          deleted file mode 100644
          index afb446115a..0000000000
          --- a/.changesets/maint_geal_query_planner_cache_key_improvements.md
          +++ /dev/null
          @@ -1,8 +0,0 @@
          -### Query planner cache key improvements ([Issue #5160](https://github.com/apollographql/router/issues/5160))
          -
          -> [!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.
          -
          -Several performance improvements have been implemented for query plan cache key generation. In particular, the distributed cache's key format has changed, which adds prefixes to the different key segments to help in debugging.
          -
          -By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/6206
          \ No newline at end of file
          diff --git a/CHANGELOG.md b/CHANGELOG.md
          index bb4866bf62..bd46bf9f90 100644
          --- a/CHANGELOG.md
          +++ b/CHANGELOG.md
          @@ -4,6 +4,296 @@ 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.58.0] - 2024-11-27
          +
          +> [!IMPORTANT]
          +> If you have enabled [Distributed query plan caching](https://www.apollographql.com/docs/router/configuration/distributed-caching/#distributed-query-plan-caching), this release contains changes which necessarily alter 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.
          +
          +## ๐Ÿš€ Features
          +
          +### Support DNS resolution strategy configuration ([PR #6109](https://github.com/apollographql/router/pull/6109))
          +
          +The router now supports a configurable DNS resolution strategy for the URLs of coprocessors and subgraphs.
          +The new option is called `dns_resolution_strategy` and supports the following values:
          +* `ipv4_only` - Only query for `A` (IPv4) records.
          +* `ipv6_only` - Only query for `AAAA` (IPv6) records.
          +* `ipv4_and_ipv6` - Query for both `A` (IPv4) and `AAAA` (IPv6) records in parallel.
          +* `ipv6_then_ipv4` - Query for `AAAA` (IPv6) records first; if that fails, query for `A` (IPv4) records.
          +* `ipv4_then_ipv6`(default) - Query for `A` (IPv4) records first; if that fails, query for `AAAA` (IPv6) records.
          +
          +You can change the DNS resolution strategy applied to a subgraph's URL:
          +
          +```yaml title="router.yaml"
          +traffic_shaping:
          +  all:
          +    dns_resolution_strategy: ipv4_then_ipv6
          +
          +```
          +
          +You can also change the DNS resolution strategy applied to a coprocessor's URL:
          +
          +```yaml title="router.yaml"
          +coprocessor:
          +  url: http://coprocessor.example.com:8081
          +  client:
          +    dns_resolution_strategy: ipv4_then_ipv6
          +
          +```
          +
          +By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6109
          +
          +### Configuration options for HTTP/1 max headers and buffer limits ([PR #6194](https://github.com/apollographql/router/pull/6194))
          +
          +This update introduces configuration options that allow you to adjust the maximum number of HTTP/1 request headers and the maximum buffer size allocated for headers.
          +
          +By default, the router accepts HTTP/1 requests with up to 100 headers and allocates ~400 KiB of buffer space to store them. If you need to handle requests with more headers or require a different buffer size, you can now configure these limits in the router's configuration file:
          +```yaml
          +limits:
          +  http1_request_max_headers: 200
          +  http1_request_max_buf_size: 200kib
          +```
          +
          +If you are using the router as a Rust crate, the `http1_request_max_buf_size` option requires the `hyper_header_limits` feature and also necessitates using Apollo's fork of the Hyper crate until the [changes are merged upstream](https://github.com/hyperium/hyper/pull/3523).
          +You can include this fork by adding the following patch to your Cargo.toml file:
          +```toml
          +[patch.crates-io]
          +"hyper" = { git = "https://github.com/apollographql/hyper.git", tag = "header-customizations-20241108" }
          +```
          +
          +By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6194
          +
          +### Compress subgraph operations by generating fragments ([PR #6013](https://github.com/apollographql/router/pull/6013))
          +
          +The router now compresses operations sent to subgraphs by default by generating fragment
          +definitions and using them in the operation.
          +
          +This change enables `generate_query_fragments` by default while disabling `experimental_reuse_query_fragments`. When enabled, `experimental_reuse_query_fragments` attempts to intelligently reuse the fragment definitions
          +from the original operation. However, fragment generation with `generate_query_fragments` is much faster and produces better outputs in most cases.
          +
          +If you are relying on the shape of fragments in your subgraph operations or tests, you can opt out of the new algorithm with the configuration below. 
          +
          +> Note: The subgraph operations generated by the query planner are not guaranteed consistent release over release. We strongly recommend against relying on the shape of planned subgraph operations, as new router features and optimizations will continuously affect it. We plan to remove `experimental_reuse_query_fragments` in a future release.
          +
          +```yaml
          +supergraph:
          +  generate_query_fragments: false
          +  experimental_reuse_query_fragments: true
          +```
          +
          +By [@lrlna](https://github.com/lrlna) in https://github.com/apollographql/router/pull/6013
          +
          +### Add subgraph request id ([PR #5858](https://github.com/apollographql/router/pull/5858))
          +
          +The router now supports a subgraph request ID that is a unique string identifying a subgraph request and response. It allows plugins and coprocessors to keep some state per subgraph request by matching on this ID. It's available in coprocessors as `subgraphRequestId` and Rhai scripts as `request.subgraph.id` and `response.subgraph.id`.
          +
          +
          +By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/5858
          +
          +### Add `extensions.service` for all subgraph errors ([PR #6191](https://github.com/apollographql/router/pull/6191))
          +
          +
          +For improved debuggability, the router now supports adding a subgraph's name as an extension to all errors originating from the subgraph.
          +
          +If `include_subgraph_errors` is `true` for a particular subgraph, all errors originating in this subgraph will have the subgraph's name exposed as a `service` extension.
          +
          +You can enable subgraph errors with the following configuration:
          +```yaml title="router.yaml"
          +include_subgraph_errors:
          +  all: true # Propagate errors from all subgraphs
          +```
          +> Note: This option is enabled by default by the router's [dev mode](https://www.apollographql.com/docs/graphos/reference/router/configuration#dev-mode-defaults).
          +
          +Consequently, when a subgraph returns an error, it will have a `service` extension with the subgraph name as its value. The following example shows the extension for a `products` subgraph:
          +
          +```json
          +{
          +  "data": null,
          +  "errors": [
          +    {
          +      "message": "Invalid product ID",
          +      "path": [],
          +      "extensions": {
          +        "service": "products"
          +      }
          +    }
          +  ]
          +}
          +```
          +
          +By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6191
          +
          +### Add `@context` support in the native query planner ([PR #6310](https://github.com/apollographql/router/pull/6310))
          +
          +The [`@context`](https://www.apollographql.com/docs/graphos/reference/federation/directives#context) feature is now available in the [native query planner](https://www.apollographql.com/docs/graphos/routing/query-planning/native-query-planner).
          +This brings the native query planner to feature parity with the legacy query planner for all Federation v2 graphs. The native query planner can be enabled with the following configuration:
          +```yaml, filename=router.yaml
          +experimental_query_planner_mode: new
          +```
          +
          +
          +By [@clenfest](https://github.com/clenfest), [@TylerBloom](https://github.com/TylerBloom) in https://github.com/apollographql/router/pull/6310
          +
          +## ๐Ÿ› Fixes
          +
          +### Remove noisy demand control logs ([PR #6192](https://github.com/apollographql/router/pull/6192))
          +
          +Demand control no longer logs warnings when a subgraph response is missing a requested field.
          +
          +By [@tninesling](https://github.com/tninesling) in https://github.com/apollographql/router/pull/6192
          +
          +### Renamed headers' original values can again be propagated ([PR #6281](https://github.com/apollographql/router/pull/6281))
          +
          +[PR #4535](https://github.com/apollographql/router/pull/4535) introduced a regression where the following header propagation config would not work:
          +
          +```yaml
          +headers:
          +- propagate:
          +    named: a
          +    rename: b
          +- propagate:
          +    named: a
          +    rename: c
          +```
          +
          +The goal of the original PR was to prevent multiple headers from being mapped to a single target header. However, it did not consider renames and instead prevented multiple mappings from the same source header. 
          +The router now propagates headers properly and ensures that a target header is only propagated to once.
          +
          +By [@BrynCooke](https://github.com/BrynCooke) in https://github.com/apollographql/router/pull/6281
          +
          +### Introspection response deduplication should always produce results ([Issue #6249](https://github.com/apollographql/router/issues/6249))
          +
          +To reduce CPU usage, query planning and introspection queries are deduplicated. In some cases, deduplicated introspection queries were not receiving their result. This issue has been fixed, and the router now sends results in all cases.
          +
          +By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/6257
          +
          +### Don't log response data upon notification failure for subgraph batching ([PR #6150](https://github.com/apollographql/router/pull/6150))
          +
          +For a subgraph batching operation, the router now doesn't log the entire subgraph response when failing to notify a waiting batch participant. This saves the router from logging the large amount of data (PII and/or non-PII data) that a subgraph response may contain.
          +
          +By [@garypen](https://github.com/garypen) in https://github.com/apollographql/router/pull/6150
          +
          +### Move heavy computation to a thread pool with a priority queue ([PR #6247](https://github.com/apollographql/router/pull/6247))
          +
          +The router now avoids blocking threads when executing asynchronous code by using a thread pool with a priority queue.
          +
          +This improves the performance of the following components that can take non-trivial amounts of CPU time:
          +
          +* GraphQL parsing
          +* GraphQL validation
          +* Query planning
          +* Schema introspection
          +
          +The size of the thread pool is based on the number of available CPU cores.
          +
          +The thread pool replaces the router's prior implementation that used Tokioโ€™s [`spawn_blocking`](https://docs.rs/tokio/latest/tokio/task/fn.spawn_blocking.html).
          +
          +`apollo.router.compute_jobs.queued` is a new gauge metric for the number of items in the thread pool's priority queue. 
          +
          +> Note: when the native query planner is enabled, the dedicated queue of the legacy query planner is no longer used, so the `apollo.router.query_planning.queued` metric is no longer emitted.
          +
          +By [@SimonSapin](https://github.com/SimonSapin) in https://github.com/apollographql/router/pull/6247
          +
          +### Limit the amount of GraphQL validation errors returned per response ([PR #6187](https://github.com/apollographql/router/pull/6187))
          +
          +When an invalid query is submitted, the router now returns at most one hundred GraphQL parsing and validation errors in a response. This prevents generating too large of a response for a nonsensical document.
          +
          +By [@goto-bus-stop](https://github.com/goto-bus-stop) in https://github.com/apollographql/router/pull/6187
          +
          +### Remove placeholders from file upload query variables ([PR #6293](https://github.com/apollographql/router/pull/6293))
          +
          +Previously, file upload query variables in subgraph requests incorrectly contained internal placeholders.
          +According to the [GraphQL Multipart Request Spec](https://github.com/jaydenseric/graphql-multipart-request-spec?tab=readme-ov-file#multipart-form-field-structure), these variables should be set to null.
          +This issue has been fixed by ensuring that the router complies with the specification and improving compatibility with subgraphs handling file uploads.
          +
          +By [@IvanGoncharov](https://github.com/IvanGoncharov) in https://github.com/apollographql/router/pull/6293
          +
          +### Overhead processing metrics should exclude subgraph response time when deduplication is enabled ([PR #6207](https://github.com/apollographql/router/pull/6207))
          +
          +The router's calculated overhead processing time has been fixed, where the time spent waiting for the subgraph response of a deduplicated request had been incorrectly included.
          +
          +By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/6207
          +
          +### Fix demand control panic for custom scalars that represent non-GraphQL-compliant JSON ([PR #6288](https://github.com/apollographql/router/pull/6288))
          +
          +Previously, a panic could be triggered in the router's demand control plugin with the following schema:
          +
          +```
          +scalar ArbitraryJson
          +
          +type MyInput {
          +    json: ArbitraryJson
          +}
          +
          +type Query {
          +    fetch(args: MyInput): Int
          +}
          +```
          +
          +Then, submitting the query
          +
          +```
          +query FetchData(: ArbitraryJson) {
          +    fetch(args: {
          +        json: 
          +    })
          +}
          +```
          +
          +and variables
          +
          +```
          +{
          +    "myJsonValue": {
          +        "field.with.dots": 1
          +    }
          +}
          +```
          +
          +During scoring, the demand control plugin would attempt to convert the variable structure into a GraphQL-compliant structure requiring valid GraphQL names as keys. The dot characters in the keys however would cause a panic. 
          +
          +With this fix, only the GraphQL compliant part of the input object is scored, and the arbitrary JSON marked by the custom scalar is scored as an opaque scalar (similar to how built-ins like `Int` or `String` are processed).
          +
          +By [@tninesling](https://github.com/tninesling) in https://github.com/apollographql/router/pull/6288
          +
          +### Fix incorrect overriding of concrete type names with interface names when merging responses ([PR #6250](https://github.com/apollographql/router/pull/6250))
          +
          +When using `@interfaceObject`, differing pieces of data can come back with either concrete types or interface types depending on the source. Previously, receiving the data in a particular order could incorrectly result in the interface name of a type overwriting its concrete name.
          +
          +To make the response merging order-agnostic, the router now checks the schema to ensure concrete types are not overwritten with interfaces or less specific types.
          +
          +By [@tninesling](https://github.com/tninesling) in https://github.com/apollographql/router/pull/6250
          +
          +## ๐Ÿ›  Maintenance
          +
          +### Query planner cache key improvements ([Issue #5160](https://github.com/apollographql/router/issues/5160))
          +
          +Several performance improvements have been implemented for query plan cache key generation. In particular, the distributed cache's key format has changed, which adds prefixes to the different key segments to help in debugging.
          +
          +By [@Geal](https://github.com/Geal) in https://github.com/apollographql/router/pull/6206
          +
          +### Add entity caching invalidation configuration metrics ([PR #6286](https://github.com/apollographql/router/pull/6286))
          +
          +We've added metrics for our analytics to know if entity caching invalidation is enabled.
          +
          +By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/6286
          +
          +### Avoid creating stub span for supergraph events if current span exists ([PR #6096](https://github.com/apollographql/router/pull/6096))
          +
          +The router optimized its telemetry implementation by not creating a redundant span when it already has a span available to use the span's extensions for supergraph events.
          +
          +By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/6096
          +
          +## ๐Ÿ“š Documentation
          +
          +### Clarify docs for authorization directive composition ([PR #6216](https://github.com/apollographql/router/pull/6216))
          +
          +The docs for [authorization directive composition](https://www.apollographql.com/docs/graphos/routing/security/authorization#composition-and-federation) have been clarified, including corrected code examples.
          +
          +
          +By [@Meschreiber](https://github.com/Meschreiber) in https://github.com/apollographql/router/pull/6216
          +
          +
          +
           # [1.57.1] - 2024-10-31
           
           ## ๐Ÿ› Fixes
          diff --git a/Cargo.lock b/Cargo.lock
          index c9180eda83..57a87514d6 100644
          --- a/Cargo.lock
          +++ b/Cargo.lock
          @@ -178,7 +178,7 @@ dependencies = [
           
           [[package]]
           name = "apollo-federation"
          -version = "1.58.0-rc.3"
          +version = "1.58.0"
           dependencies = [
            "apollo-compiler",
            "derive_more",
          @@ -231,7 +231,7 @@ dependencies = [
           
           [[package]]
           name = "apollo-router"
          -version = "1.58.0-rc.3"
          +version = "1.58.0"
           dependencies = [
            "access-json",
            "ahash",
          @@ -399,7 +399,7 @@ dependencies = [
           
           [[package]]
           name = "apollo-router-benchmarks"
          -version = "1.58.0-rc.3"
          +version = "1.58.0"
           dependencies = [
            "apollo-parser",
            "apollo-router",
          @@ -415,7 +415,7 @@ dependencies = [
           
           [[package]]
           name = "apollo-router-scaffold"
          -version = "1.58.0-rc.3"
          +version = "1.58.0"
           dependencies = [
            "anyhow",
            "cargo-scaffold",
          diff --git a/apollo-federation/Cargo.toml b/apollo-federation/Cargo.toml
          index 716dd01f6b..c0103f435e 100644
          --- a/apollo-federation/Cargo.toml
          +++ b/apollo-federation/Cargo.toml
          @@ -1,6 +1,6 @@
           [package]
           name = "apollo-federation"
          -version = "1.58.0-rc.3"
          +version = "1.58.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 097a7501df..359391b4a7 100644
          --- a/apollo-router-benchmarks/Cargo.toml
          +++ b/apollo-router-benchmarks/Cargo.toml
          @@ -1,6 +1,6 @@
           [package]
           name = "apollo-router-benchmarks"
          -version = "1.58.0-rc.3"
          +version = "1.58.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 ca32fb0d3d..8b68e56a12 100644
          --- a/apollo-router-scaffold/Cargo.toml
          +++ b/apollo-router-scaffold/Cargo.toml
          @@ -1,6 +1,6 @@
           [package]
           name = "apollo-router-scaffold"
          -version = "1.58.0-rc.3"
          +version = "1.58.0"
           authors = ["Apollo Graph, Inc. "]
           edition = "2021"
           license = "Elastic-2.0"
          diff --git a/apollo-router-scaffold/templates/base/Cargo.template.toml b/apollo-router-scaffold/templates/base/Cargo.template.toml
          index 162f4f70b9..00b111b264 100644
          --- a/apollo-router-scaffold/templates/base/Cargo.template.toml
          +++ b/apollo-router-scaffold/templates/base/Cargo.template.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.58.0-rc.3"
          +apollo-router = "1.58.0"
           {{/if}}
           {{/if}}
           async-trait = "0.1.52"
          diff --git a/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml b/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml
          index 6f29bfeaff..db2a939c2a 100644
          --- a/apollo-router-scaffold/templates/base/xtask/Cargo.template.toml
          +++ b/apollo-router-scaffold/templates/base/xtask/Cargo.template.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.58.0-rc.3" }
          +apollo-router-scaffold = { git = "https://github.com/apollographql/router.git", tag = "v1.58.0" }
           {{/if}}
           {{/if}}
           anyhow = "1.0.58"
          diff --git a/apollo-router/Cargo.toml b/apollo-router/Cargo.toml
          index 2b2e904f0c..f2cedca917 100644
          --- a/apollo-router/Cargo.toml
          +++ b/apollo-router/Cargo.toml
          @@ -1,6 +1,6 @@
           [package]
           name = "apollo-router"
          -version = "1.58.0-rc.3"
          +version = "1.58.0"
           authors = ["Apollo Graph, Inc. "]
           repository = "https://github.com/apollographql/router/"
           documentation = "https://docs.rs/apollo-router"
          @@ -66,7 +66,7 @@ features = ["docs_rs"]
           access-json = "0.1.0"
           anyhow = "1.0.86"
           apollo-compiler.workspace = true
          -apollo-federation = { path = "../apollo-federation", version = "=1.58.0-rc.3" }
          +apollo-federation = { path = "../apollo-federation", version = "=1.58.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 c982ce6391..e69604eb8c 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.58.0-rc.3
          +    image: ghcr.io/apollographql/router:v1.58.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 f5a87af6ab..8225d7799a 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.58.0-rc.3
          +    image: ghcr.io/apollographql/router:v1.58.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 9fe89d4aae..a84a7f1fcf 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.58.0-rc.3
          +    image: ghcr.io/apollographql/router:v1.58.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 013cdd9cc7..51cf64fa63 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.58.0-rc.3
          +version: 1.58.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.58.0-rc.3"
          +appVersion: "v1.58.0"
          diff --git a/helm/chart/router/README.md b/helm/chart/router/README.md
          index 7db9fcec88..c68ab5cd8b 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.58.0-rc.3](https://img.shields.io/badge/Version-1.58.0--rc.3-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.58.0-rc.3](https://img.shields.io/badge/AppVersion-v1.58.0--rc.3-informational?style=flat-square)
          +![Version: 1.58.0](https://img.shields.io/badge/Version-1.58.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.58.0](https://img.shields.io/badge/AppVersion-v1.58.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.58.0-rc.3
          +helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0
           ```
           
           ## Install Chart
          @@ -19,7 +19,7 @@ helm pull oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0-rc.3
           **Important:** only helm3 is supported
           
           ```console
          -helm upgrade --install [RELEASE_NAME] oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0-rc.3 --values my-values.yaml
          +helm upgrade --install [RELEASE_NAME] oci://ghcr.io/apollographql/helm-charts/router --version 1.58.0 --values my-values.yaml
           ```
           
           _See [configuration](#configuration) below._
          diff --git a/licenses.html b/licenses.html
          index a2a75adc9c..37ceccad5d 100644
          --- a/licenses.html
          +++ b/licenses.html
          @@ -48,9 +48,9 @@ 

          Overview of licenses:

        • MIT License (154)
        • BSD 3-Clause "New" or "Revised" License (11)
        • ISC License (8)
        • +
        • Elastic License 2.0 (6)
        • Mozilla Public License 2.0 (5)
        • BSD 2-Clause "Simplified" License (4)
        • -
        • Elastic License 2.0 (3)
        • Creative Commons Zero v1.0 Universal (2)
        • OpenSSL License (1)
        • Unicode License Agreement - Data Files and Software (2016) (1)
        • @@ -12694,6 +12694,9 @@

          Elastic License 2.0

          Used by:

          Copyright 2021 Apollo Graph, Inc.
           
          diff --git a/scripts/install.sh b/scripts/install.sh
          index 80c5beed67..6446019f5b 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.58.0-rc.3"
          +PACKAGE_VERSION="v1.58.0"
           
           download_binary() {
               downloader --check
          
  • e^k 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%0Axq=_1Kj5FO&QAcmv8blifErDa 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 literal 0 HcmV?d00001 diff --git a/docs/source/images/cloud-dedicated/create-new-graph.jpg b/docs/source/images/cloud-dedicated/create-new-graph.jpg new file mode 100644 index 0000000000000000000000000000000000000000..249c9896d3e326d573aa53c684b956f16b8e3486 GIT binary patch literal 266839 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 J&K$Nn_%~;_ije>S literal 0 HcmV?d00001 diff --git a/docs/source/images/cloud-dedicated/create-resource-share-final.jpg b/docs/source/images/cloud-dedicated/create-resource-share-final.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6a2b5ce958a127e717ad4c18946e101284e54ffc GIT binary patch literal 33250 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 z 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∈ztv{&Js);Jk8?g<|%-*w& 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