Skip to content

Commit d7a847b

Browse files
committed
refactor: add inject labels middleware
Signed-off-by: Gustavo Inacio <[email protected]>
1 parent eb305e0 commit d7a847b

File tree

4 files changed

+155
-6
lines changed

4 files changed

+155
-6
lines changed

crates/service/src/middleware.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@
33

44
mod inject_allocation;
55
mod inject_deployment;
6+
mod inject_labels;
67
mod inject_receipt;
78
mod inject_sender;
9+
mod metrics;
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// Copyright 2023-, Edge & Node, GraphOps, and Semiotic Labs.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
//! Injects Metric Labels
5+
//!
6+
//! Require Sender, Allocation and Deployment extensions
7+
8+
use std::sync::Arc;
9+
10+
use axum::{extract::Request, middleware::Next, response::Response};
11+
use thegraph_core::DeploymentId;
12+
13+
use super::{
14+
inject_allocation::Allocation,
15+
inject_sender::Sender,
16+
metrics::{MetricLabelProvider, MetricLabels},
17+
};
18+
19+
const NO_DEPLOYMENT_ID: &str = "no-deployment";
20+
const NO_ALLOCATION: &str = "no-allocation";
21+
const NO_SENDER: &str = "no-sender";
22+
23+
#[derive(Clone, Default)]
24+
pub struct SenderAllocationDeploymentLabels {
25+
sender: Option<String>,
26+
allocation: Option<String>,
27+
deployment_id: Option<String>,
28+
}
29+
30+
impl MetricLabelProvider for SenderAllocationDeploymentLabels {
31+
fn get_labels(&self) -> Vec<&str> {
32+
let mut list = vec![];
33+
if let Some(deployment_id) = &self.deployment_id {
34+
list.push(deployment_id.as_str());
35+
} else {
36+
list.push(NO_DEPLOYMENT_ID);
37+
}
38+
if let Some(allocation) = &self.allocation {
39+
list.push(allocation.as_str());
40+
} else {
41+
list.push(NO_ALLOCATION);
42+
}
43+
if let Some(sender) = &self.sender {
44+
list.push(sender.as_str());
45+
} else {
46+
list.push(NO_SENDER);
47+
}
48+
list
49+
}
50+
}
51+
52+
pub async fn labels_middleware(mut request: Request, next: Next) -> Response {
53+
let sender: Option<String> = request
54+
.extensions()
55+
.get::<Sender>()
56+
.map(|s| s.clone().into());
57+
58+
let allocation: Option<String> = request
59+
.extensions()
60+
.get::<Allocation>()
61+
.map(|s| s.clone().into());
62+
63+
let deployment_id: Option<String> = request
64+
.extensions()
65+
.get::<DeploymentId>()
66+
.map(|s| s.clone().to_string());
67+
68+
let labels: MetricLabels = Arc::new(SenderAllocationDeploymentLabels {
69+
sender,
70+
allocation,
71+
deployment_id,
72+
});
73+
request.extensions_mut().insert(labels);
74+
75+
next.run(request).await
76+
}
77+
78+
#[cfg(test)]
79+
mod tests {
80+
use crate::middleware::{
81+
inject_allocation::Allocation, inject_sender::Sender, metrics::MetricLabels,
82+
};
83+
84+
use super::labels_middleware;
85+
86+
use alloy::primitives::Address;
87+
use axum::{
88+
body::Body,
89+
http::{Extensions, Request},
90+
middleware::from_fn,
91+
routing::get,
92+
Router,
93+
};
94+
use reqwest::StatusCode;
95+
use test_assets::ESCROW_SUBGRAPH_DEPLOYMENT;
96+
use tower::ServiceExt;
97+
98+
#[tokio::test]
99+
async fn test_receipt_middleware() {
100+
let middleware = from_fn(labels_middleware);
101+
102+
let deployment = *ESCROW_SUBGRAPH_DEPLOYMENT;
103+
let sender = Address::ZERO;
104+
let allocation = Address::ZERO;
105+
106+
let handle = move |extensions: Extensions| async move {
107+
let metrics = extensions
108+
.get::<MetricLabels>()
109+
.expect("Should decode tap receipt");
110+
assert_eq!(
111+
metrics.get_labels(),
112+
vec![
113+
&deployment.to_string(),
114+
&allocation.to_string(),
115+
&sender.to_string(),
116+
]
117+
);
118+
Body::empty()
119+
};
120+
121+
let app = Router::new().route("/", get(handle)).layer(middleware);
122+
123+
let res = app
124+
.oneshot(
125+
Request::builder()
126+
.uri("/")
127+
.extension(Sender(sender))
128+
.extension(deployment)
129+
.extension(Allocation(allocation))
130+
.body(Body::empty())
131+
.unwrap(),
132+
)
133+
.await
134+
.unwrap();
135+
assert_eq!(res.status(), StatusCode::OK);
136+
}
137+
}

crates/service/src/middleware/inject_sender.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright 2023-, Edge & Node, GraphOps, and Semiotic Labs.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use alloy::dyn_abi::Eip712Domain;
4+
use alloy::{dyn_abi::Eip712Domain, primitives::Address};
55
use axum::{
66
extract::{Request, State},
77
middleware::Next,
@@ -20,11 +20,11 @@ pub struct SenderState {
2020
}
2121

2222
#[derive(Clone)]
23-
pub struct Sender(String);
23+
pub struct Sender(pub Address);
2424

2525
impl From<Sender> for String {
2626
fn from(value: Sender) -> Self {
27-
value.0
27+
value.0.to_string()
2828
}
2929
}
3030

@@ -39,7 +39,7 @@ pub async fn sender_middleware(
3939
.escrow_accounts
4040
.borrow()
4141
.get_sender_for_signer(&signer)?;
42-
request.extensions_mut().insert(Sender(sender.to_string()));
42+
request.extensions_mut().insert(Sender(sender));
4343
}
4444

4545
Ok(next.run(request).await)
@@ -60,7 +60,9 @@ mod tests {
6060
};
6161
use indexer_monitor::EscrowAccounts;
6262
use reqwest::StatusCode;
63-
use test_assets::{create_signed_receipt, ESCROW_ACCOUNTS_BALANCES, ESCROW_ACCOUNTS_SENDERS_TO_SIGNERS};
63+
use test_assets::{
64+
create_signed_receipt, ESCROW_ACCOUNTS_BALANCES, ESCROW_ACCOUNTS_SENDERS_TO_SIGNERS,
65+
};
6466
use tokio::sync::watch;
6567
use tower::ServiceExt;
6668

@@ -80,7 +82,7 @@ mod tests {
8082

8183
async fn handle(extensions: Extensions) -> Body {
8284
let sender = extensions.get::<Sender>().expect("Should contain sender");
83-
assert_eq!(sender.0, test_assets::TAP_SENDER.1.to_string());
85+
assert_eq!(sender.0, test_assets::TAP_SENDER.1);
8486
Body::empty()
8587
}
8688

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
use std::sync::Arc;
2+
3+
4+
pub type MetricLabels = Arc<dyn MetricLabelProvider + 'static + Send + Sync>;
5+
6+
pub trait MetricLabelProvider {
7+
fn get_labels(&self) -> Vec<&str>;
8+
}

0 commit comments

Comments
 (0)