Skip to content

Commit d669c27

Browse files
committed
Add TelemetryPolicy
1 parent 457bd53 commit d669c27

File tree

5 files changed

+92
-14
lines changed

5 files changed

+92
-14
lines changed

sdk/core/Cargo.toml

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,26 @@ categories = ["api-bindings"]
1313
edition = "2018"
1414

1515
[dependencies]
16+
async-trait = "0.1"
17+
bytes = "1.0"
1618
chrono = "0.4"
17-
http = "0.2"
19+
clap = "2.33.3"
20+
dyn-clone = "1.0"
1821
futures = "0.3"
22+
http = "0.2"
1923
hyper = { version = "0.14", optional = true }
24+
hyper-rustls = { version = "0.22", optional = true }
2025
log = "0.4"
21-
thiserror = "1.0"
26+
oauth2 = "4.0.0"
27+
rand = "0.7"
28+
reqwest = { version = "0.11", features = ["stream"], optional = true }
29+
rustc_version = "0.3.3"
2230
serde = "1.0"
2331
serde_derive = "1.0"
2432
serde_json = "1.0"
33+
thiserror = "1.0"
2534
url = "2.2"
2635
uuid = { version = "0.8" }
27-
bytes = "1.0"
28-
hyper-rustls = { version = "0.22", optional = true }
29-
async-trait = "0.1"
30-
oauth2 = "4.0.0"
31-
reqwest = { version = "0.11", features = ["stream"], optional = true }
32-
rand = "0.7"
33-
dyn-clone = "1.0"
3436

3537
[dev-dependencies]
3638
env_logger = "0.8"

sdk/core/src/pipeline.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::policies::{Policy, PolicyResult};
1+
use crate::policies::{Policy, PolicyResult, TelemetryPolicy};
22
use crate::{Context, Request, Response};
33
use std::sync::Arc;
44

@@ -8,10 +8,10 @@ use std::sync::Arc;
88
///
99
/// 1. Per call policies are executed. Per call policies can fail and bail out of the pipeline
1010
/// immediately.
11-
/// 2. Retry policy. It allows to reexecute the following policies.
12-
/// 3. Per retry policies. Per retry polices are always executed at least once but are reexecuted
11+
/// 2. Retry policy. It allows to re-execute the following policies.
12+
/// 3. Per retry policies. Per retry polices are always executed at least once but are re-executed
1313
/// in case of retries.
14-
/// 4. Transport policy. Transtport policy is always the last policy and is the policy that
14+
/// 4. Transport policy. Transport policy is always the last policy and is the policy that
1515
/// actually constructs the `Response` to be passed up the pipeline.
1616
///
1717
/// A pipeline is immutable. In other words a policy can either succeed and call the following
@@ -31,7 +31,10 @@ impl Pipeline {
3131
transport_policy: Arc<dyn Policy>,
3232
) -> Self {
3333
let mut pipeline =
34-
Vec::with_capacity(per_call_policies.len() + per_retry_policies.len() + 2);
34+
Vec::<Arc<dyn Policy>>::with_capacity(per_call_policies.len() + per_retry_policies.len() + 3);
35+
36+
// TODO: Create pipeline from ClientOptions which should contain user-specified policies + client-added policies.
37+
pipeline.push(Arc::new(TelemetryPolicy::default()));
3538

3639
pipeline.extend_from_slice(&per_call_policies);
3740
pipeline.push(retry);

sdk/core/src/policies/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
mod retry_policies;
2+
mod telemetry_policy;
23
mod transport;
34

45
use crate::{Context, Request, Response};
56
pub use retry_policies::*;
67
use std::error::Error;
78
use std::sync::Arc;
9+
pub use telemetry_policy::*;
810
pub use transport::*;
911

1012
pub type PolicyResult<T> = Result<T, Box<dyn Error + Send + Sync>>;
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
use crate::{Context, Request, Response};
2+
use crate::policies::{Policy, PolicyResult};
3+
4+
use http::{HeaderValue, header::USER_AGENT};
5+
use rustc_version::{Version, version};
6+
use std::env::consts::{ARCH, OS};
7+
use std::sync::Arc;
8+
9+
#[derive(Clone, Debug, Default)]
10+
pub struct TelemetryOptions {
11+
application_id: Option<String>,
12+
}
13+
14+
impl TelemetryOptions {
15+
pub fn new(application_id: Option<String>) -> Self {
16+
Self { application_id }
17+
}
18+
}
19+
20+
#[derive(Clone, Debug)]
21+
pub struct TelemetryPolicy {
22+
header: String,
23+
}
24+
25+
const EMPTY_VERSION: Version = Version {
26+
major: 0,
27+
minor: 0,
28+
patch: 0,
29+
pre: Vec::new(),
30+
build: Vec::new(),
31+
};
32+
33+
impl TelemetryPolicy {
34+
pub fn new(options: TelemetryOptions) -> Self {
35+
let platform_info = format!("({}; {}; {})", version().unwrap_or(EMPTY_VERSION), OS, ARCH);
36+
if let Some(application_id) = options.application_id {
37+
TelemetryPolicy {
38+
header: format!("{} azsdk-rust-{}/{} {}", application_id, clap::crate_name!(), clap::crate_version!(), platform_info),
39+
}
40+
} else {
41+
TelemetryPolicy {
42+
header: format!("azsdk-rust-{}/{} {}", clap::crate_name!(), clap::crate_version!(), platform_info),
43+
}
44+
}
45+
}
46+
}
47+
48+
impl Default for TelemetryPolicy {
49+
fn default() -> Self {
50+
TelemetryPolicy::new(TelemetryOptions::default())
51+
}
52+
}
53+
54+
#[async_trait::async_trait]
55+
impl Policy for TelemetryPolicy {
56+
async fn send(
57+
&self,
58+
ctx: &mut Context,
59+
request: &mut Request,
60+
next: &[Arc<dyn Policy>],
61+
) -> PolicyResult<Response> {
62+
63+
request.headers_mut().insert(USER_AGENT, HeaderValue::from_str(&self.header).unwrap());
64+
65+
next[0].send(ctx, request, &next[1..]).await
66+
}
67+
}

sdk/core/src/request.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ impl Request {
4545
&self.headers
4646
}
4747

48+
pub fn headers_mut(&mut self) -> &mut HeaderMap {
49+
&mut self.headers
50+
}
51+
4852
pub fn body(&self) -> &Body {
4953
&self.body
5054
}

0 commit comments

Comments
 (0)