Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,375 changes: 2,301 additions & 74 deletions Cargo.lock

Large diffs are not rendered by default.

25 changes: 22 additions & 3 deletions bin/router/src/pipeline/execution.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::borrow::Cow;
use std::collections::HashMap;
use std::sync::Arc;

Expand All @@ -6,9 +7,12 @@ use crate::pipeline::error::{PipelineError, PipelineErrorFromAcceptHeader, Pipel
use crate::pipeline::normalize::GraphQLNormalizationPayload;
use crate::shared_state::RouterSharedState;
use hive_router_plan_executor::execute_query_plan;
use hive_router_plan_executor::execution::plan::{PlanExecutionOutput, QueryPlanExecutionContext};
use hive_router_plan_executor::execution::plan::{
ClientRequestDetails, OperationDetails, PlanExecutionOutput, QueryPlanExecutionContext,
};
use hive_router_plan_executor::introspection::resolve::IntrospectionContext;
use hive_router_query_planner::planner::plan_nodes::QueryPlan;
use hive_router_query_planner::state::supergraph_state::OperationKind;
use http::HeaderName;
use ntex::web::HttpRequest;

Expand All @@ -22,8 +26,9 @@ enum ExposeQueryPlanMode {
}

#[inline]
pub async fn execute_plan(
pub async fn execute_plan<'a>(
req: &mut HttpRequest,
query: Cow<'a, str>,
app_state: &Arc<RouterSharedState>,
normalized_payload: &Arc<GraphQLNormalizationPayload>,
query_plan_payload: &Arc<QueryPlan>,
Expand Down Expand Up @@ -66,7 +71,21 @@ pub async fn execute_plan(
headers_plan: &app_state.headers_plan,
variable_values: &variable_payload.variables_map,
extensions,
upstream_headers: req.headers(),
client_request: ClientRequestDetails {
method: req.method().clone(),
url: req.uri().clone(),
headers: req.headers(),
operation: OperationDetails {
name: normalized_payload.operation_for_plan.name.clone(),
kind: match normalized_payload.operation_for_plan.operation_kind {
Some(OperationKind::Query) => "query",
Some(OperationKind::Mutation) => "mutation",
Some(OperationKind::Subscription) => "subscription",
None => "query",
},
query,
},
},
introspection_context: &introspection_context,
operation_type_name: normalized_payload.root_type_name,
executors: &app_state.subgraph_executor_map,
Expand Down
4 changes: 3 additions & 1 deletion bin/router/src/pipeline/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::sync::Arc;
use std::{borrow::Cow, sync::Arc};

use hive_router_plan_executor::execution::plan::PlanExecutionOutput;
use hive_router_query_planner::utils::cancellation::CancellationToken;
Expand Down Expand Up @@ -92,6 +92,7 @@ pub async fn execute_pipeline(
let progressive_override_ctx = request_override_context()?;
let normalize_payload =
normalize_request_with_cache(req, state, &execution_request, &parser_payload).await?;
let query = Cow::Owned(execution_request.query.clone());
let variable_payload =
coerce_request_variables(req, state, execution_request, &normalize_payload)?;

Expand All @@ -109,6 +110,7 @@ pub async fn execute_pipeline(

let execution_result = execute_plan(
req,
query,
state,
&normalize_payload,
&query_plan_payload,
Expand Down
134 changes: 132 additions & 2 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,34 @@ Static value provided in the config.
|**value**|`string`||yes|



**Option 2 (optional):**
A dynamic value computed by a VRL expression.

This allows you to generate header values based on the incoming request,
subgraph name, and (for response rules) subgraph response headers.
The expression has access to a context object with `.request`, `.subgraph`,
and `.response` fields.

For more information on the available functions and syntax, see the
[VRL documentation](https://vrl.dev/).

### Example
```yaml
# Insert a header with a value derived from another header.
- insert:
name: x-auth-scheme
expression: 'split(.request.headers.authorization, " ")[0] ?? "none"'
```


**Properties**

|Name|Type|Description|Required|
|----|----|-----------|--------|
|**expression**|`string`||yes|


<a name="headersallresponse"></a>
#### headers\.all\.response\[\]: array,null

Expand Down Expand Up @@ -405,7 +433,8 @@ For never-join headers, appends another occurrence (multiple lines).
**Example**

```yaml
insert: {}
insert:
algorithm: null

```

Expand Down Expand Up @@ -549,6 +578,7 @@ Insert a header with a static value.

|Name|Type|Description|Required|
|----|----|-----------|--------|
|**algorithm**||How to merge values across multiple subgraph responses.<br/>Default: `Last` (overwrite).<br/>|no|
|**name**|`string`|Header name to insert or overwrite (case-insensitive).<br/>|yes|


Expand All @@ -563,6 +593,41 @@ Static value provided in the config.
|**value**|`string`||yes|



**Option 2 (optional):**
A dynamic value computed by a VRL expression.

This allows you to generate header values based on the incoming request,
subgraph name, and (for response rules) subgraph response headers.
The expression has access to a context object with `.request`, `.subgraph`,
and `.response` fields.

For more information on the available functions and syntax, see the
[VRL documentation](https://vrl.dev/).

### Example
```yaml
# Insert a header with a value derived from another header.
- insert:
name: x-auth-scheme
expression: 'split(.request.headers.authorization, " ")[0] ?? "none"'
```


**Properties**

|Name|Type|Description|Required|
|----|----|-----------|--------|
|**expression**|`string`||yes|


**Example**

```yaml
algorithm: null

```

<a name="headerssubgraphs"></a>
### headers\.subgraphs: object,null

Expand Down Expand Up @@ -852,6 +917,34 @@ Static value provided in the config.
|**value**|`string`||yes|



**Option 2 (optional):**
A dynamic value computed by a VRL expression.

This allows you to generate header values based on the incoming request,
subgraph name, and (for response rules) subgraph response headers.
The expression has access to a context object with `.request`, `.subgraph`,
and `.response` fields.

For more information on the available functions and syntax, see the
[VRL documentation](https://vrl.dev/).

### Example
```yaml
# Insert a header with a value derived from another header.
- insert:
name: x-auth-scheme
expression: 'split(.request.headers.authorization, " ")[0] ?? "none"'
```


**Properties**

|Name|Type|Description|Required|
|----|----|-----------|--------|
|**expression**|`string`||yes|


<a name="headerssubgraphsadditionalpropertiesresponse"></a>
##### headers\.subgraphs\.additionalProperties\.response\[\]: array,null

Expand Down Expand Up @@ -936,7 +1029,8 @@ For never-join headers, appends another occurrence (multiple lines).
**Example**

```yaml
insert: {}
insert:
algorithm: null

```

Expand Down Expand Up @@ -1080,6 +1174,7 @@ Insert a header with a static value.

|Name|Type|Description|Required|
|----|----|-----------|--------|
|**algorithm**||How to merge values across multiple subgraph responses.<br/>Default: `Last` (overwrite).<br/>|no|
|**name**|`string`|Header name to insert or overwrite (case-insensitive).<br/>|yes|


Expand All @@ -1094,6 +1189,41 @@ Static value provided in the config.
|**value**|`string`||yes|



**Option 2 (optional):**
A dynamic value computed by a VRL expression.

This allows you to generate header values based on the incoming request,
subgraph name, and (for response rules) subgraph response headers.
The expression has access to a context object with `.request`, `.subgraph`,
and `.response` fields.

For more information on the available functions and syntax, see the
[VRL documentation](https://vrl.dev/).

### Example
```yaml
# Insert a header with a value derived from another header.
- insert:
name: x-auth-scheme
expression: 'split(.request.headers.authorization, " ")[0] ?? "none"'
```


**Properties**

|Name|Type|Description|Required|
|----|----|-----------|--------|
|**expression**|`string`||yes|


**Example**

```yaml
algorithm: null

```

<a name="http"></a>
## http: object

Expand Down
1 change: 1 addition & 0 deletions lib/executor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ tokio = { workspace = true, features = ["sync"] }
dashmap = { workspace = true }
ahash = "0.8.12"
regex-automata = "0.4.10"
vrl = { version = "0.27.0", features = ["compiler", "parser", "value", "diagnostic", "stdlib", "core"] }

ntex-http = "0.1.15"
hyper-tls = { version = "0.6.0", features = ["vendored"] }
Expand Down
12 changes: 4 additions & 8 deletions lib/executor/src/execution/error.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
use crate::projection::error::ProjectionError;
use crate::{headers::errors::HeaderRuleRuntimeError, projection::error::ProjectionError};

#[derive(thiserror::Error, Debug, Clone)]
pub enum PlanExecutionError {
#[error("Projection faiure: {0}")]
ProjectionFailure(ProjectionError),
}

impl From<ProjectionError> for PlanExecutionError {
fn from(error: ProjectionError) -> Self {
PlanExecutionError::ProjectionFailure(error)
}
ProjectionFailure(#[from] ProjectionError),
#[error(transparent)]
HeaderPropagation(#[from] HeaderRuleRuntimeError),
}
Loading
Loading