Skip to content

Commit

Permalink
add counters, and a test
Browse files Browse the repository at this point in the history
  • Loading branch information
o0Ignition0o committed Jul 31, 2023
1 parent 170b091 commit 5c3ee56
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ expression: "&schema"
"additionalProperties": false
}
},
"additionalProperties": false,
"nullable": true
},
"subgraph": {
Expand Down Expand Up @@ -271,6 +272,7 @@ expression: "&schema"
"type": "string"
}
},
"additionalProperties": false,
"nullable": true
},
"region": {
Expand Down Expand Up @@ -327,6 +329,7 @@ expression: "&schema"
"type": "string"
}
},
"additionalProperties": false,
"nullable": true
},
"profile_name": {
Expand All @@ -342,7 +345,8 @@ expression: "&schema"
"description": "The service you're trying to access, eg: \"s3\", \"vpc-lattice-svcs\", etc.",
"type": "string"
}
}
},
"additionalProperties": false
}
},
"additionalProperties": false
Expand Down Expand Up @@ -411,6 +415,7 @@ expression: "&schema"
"type": "string"
}
},
"additionalProperties": false,
"nullable": true
},
"region": {
Expand Down Expand Up @@ -467,6 +472,7 @@ expression: "&schema"
"type": "string"
}
},
"additionalProperties": false,
"nullable": true
},
"profile_name": {
Expand All @@ -482,7 +488,8 @@ expression: "&schema"
"description": "The service you're trying to access, eg: \"s3\", \"vpc-lattice-svcs\", etc.",
"type": "string"
}
}
},
"additionalProperties": false
}
},
"additionalProperties": false
Expand Down
30 changes: 23 additions & 7 deletions apollo-router/src/plugins/authentication/subgraph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,20 @@ pub(crate) struct SigningParamsConfig {
service_name: String,
}

#[allow(dead_code)]
fn increment_success_counter(_subgraph_name: &str) {}
#[allow(dead_code)]
fn increment_failure_counter(_subgraph_name: &str) {}
fn increment_success_counter(subgraph_name: &str) {
tracing::info!(
monotonic_counter.apollo.router.operations.authentication.aws.sigv4 = 1u64,
authentication.aws.sigv4.failed = false,
service_name = %subgraph_name,
);
}
fn increment_failure_counter(subgraph_name: &str) {
tracing::info!(
monotonic_counter.apollo.router.operations.authentication.aws.sigv4 = 1u64,
authentication.aws.sigv4.failed = true,
service_name = %subgraph_name,
);
}

pub(super) async fn make_signing_params(
config: &AuthConfig,
Expand Down Expand Up @@ -251,9 +261,11 @@ impl SubgraphAuth {
service: crate::services::subgraph::BoxService,
) -> crate::services::subgraph::BoxService {
if let Some(signing_params) = self.params_for_service(name) {
let name = name.to_string();
ServiceBuilder::new()
.checkpoint_async(move |mut req: SubgraphRequest| {
let signing_params = signing_params.clone();
let name = name.clone();
async move {
let credentials = match signing_params.credentials_provider.provide_credentials().await {
Ok(credentials) => credentials,
Expand All @@ -262,6 +274,7 @@ impl SubgraphAuth {
"Failed to serialize GraphQL body for AWS SigV4 signing, skipping signing. Error: {}",
err
);
increment_failure_counter(name.as_str());
return Ok(ControlFlow::Continue(req));
}
};
Expand All @@ -279,9 +292,10 @@ impl SubgraphAuth {
Ok(b) => b,
Err(err) => {
tracing::error!(
"Failed to serialize GraphQL body for AWS SigV4 signing, skipping signing. Error: {}",
err
);
"Failed to serialize GraphQL body for AWS SigV4 signing, skipping signing. Error: {}",
err
);
increment_failure_counter(name.as_str());
return Ok(ControlFlow::Continue(req));
}
};
Expand All @@ -302,10 +316,12 @@ impl SubgraphAuth {
Ok(output) => output,
Err(err) => {
tracing::error!("Failed to sign GraphQL request for AWS SigV4, skipping signing. Error: {}", err);
increment_failure_counter(name.as_str());
return Ok(ControlFlow::Continue(req));
}
}.into_parts();
signing_instructions.apply_to_request(&mut req.subgraph_request);
increment_success_counter(name.as_str());
Ok(ControlFlow::Continue(req))
}
}).buffered()
Expand Down
34 changes: 34 additions & 0 deletions apollo-router/tests/fixtures/subgraph_auth.router.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
telemetry:
metrics:
prometheus:
listen: 127.0.0.1:4000
enabled: true
path: /metrics
common:
attributes:
subgraph:
all:
request:
header:
- named: "x-custom-header"
rename: "custom_header"
default: "unknown"
headers:
all:
request:
- insert:
name: "x-custom-header"
value: "test_custom"
override_subgraph_url:
products: http://localhost:4005
include_subgraph_errors:
all: true
authentication:
subgraph:
all:
aws_sig_v4:
hardcoded:
access_key_id: "test"
secret_access_key: "test"
region: "us-east-1"
service_name: "test_service"
42 changes: 42 additions & 0 deletions apollo-router/tests/metrics_tests.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use std::time::Duration;

use serde_json::json;
use tower::BoxError;

use crate::common::IntegrationTest;

mod common;

const PROMETHEUS_CONFIG: &str = include_str!("fixtures/prometheus.router.yaml");
const SUBGRAPH_AUTH_CONFIG: &str = include_str!("fixtures/subgraph_auth.router.yaml");

#[tokio::test(flavor = "multi_thread")]
async fn test_metrics_reloading() -> Result<(), BoxError> {
Expand Down Expand Up @@ -69,3 +71,43 @@ async fn test_metrics_reloading() -> Result<(), BoxError> {

Ok(())
}

#[tokio::test(flavor = "multi_thread")]
async fn test_subgraph_auth_metrics() -> Result<(), BoxError> {
let mut router = IntegrationTest::builder()
.config(SUBGRAPH_AUTH_CONFIG)
.build()
.await;

router.start().await;
router.assert_started().await;

router.execute_default_query().await;
router.execute_default_query().await;

// Remove auth
router.update_config(PROMETHEUS_CONFIG).await;
router.assert_reloaded().await;
// This one will not be signed, counters shouldn't increment.
router
.execute_query(&json! {{ "query": "query { me { name } }"}})
.await;

// Get Prometheus metrics.
let metrics_response = router.get_metrics_response().await.unwrap();

// Validate metric headers.
let metrics_headers = metrics_response.headers();
assert!(
"text/plain; version=0.0.4"
== metrics_headers
.get(http::header::CONTENT_TYPE)
.unwrap()
.to_str()
.unwrap()
);

router.assert_metrics_contains(r#"apollo_router_operations_authentication_aws_sigv4_total{authentication_aws_sigv4_failed="false",service_name="apollo-router",service_name="products",otel_scope_name="apollo/router",otel_scope_version=""} 2"#, None).await;

Ok(())
}

0 comments on commit 5c3ee56

Please sign in to comment.