Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AdEx V5: Init Sentry REST API documentation (using rustdoc) #443

Merged
merged 13 commits into from
Jan 25, 2022
2 changes: 1 addition & 1 deletion primitives/src/sentry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ pub struct FetchedAnalytics {
pub segment: Option<String>,
}

/// The value of the requested analytics [`Metric`].
/// The value of the requested analytics [`crate::analytics::Metric`].
#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)]
#[serde(untagged)]
pub enum FetchedMetric {
Expand Down
10 changes: 10 additions & 0 deletions sentry/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Sentry

## REST API documentation for AdEx Protocol V5

For full details see [AIP #61](https://github.com/AmbireTech/aips/issues/61) and the tracking issue for this implementation https://github.com/AmbireTech/adex-validator-stack-rust/issues/377.

REST API documentation can be generated using `rustdoc`:

`cargo doc --all-features --open --lib`

and checking the `sentry::routes` module.

## Development

### Migrations
Expand Down
1 change: 0 additions & 1 deletion sentry/src/analytics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ pub async fn record(
(None, None) => None,
};

// TODO: tidy up this operation
batch_update
.entry(event)
.and_modify(|analytics| {
Expand Down
122 changes: 0 additions & 122 deletions sentry/src/analytics_recorder.rs

This file was deleted.

63 changes: 20 additions & 43 deletions sentry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,29 +27,22 @@ use {
routes::{
campaign,
campaign::{campaign_list, create_campaign, update_campaign},
cfg::config,
get_cfg,
get_analytics,
channel::{
add_spender_leaf, channel_list, create_validator_messages, get_accounting_for_channel,
get_all_spender_limits, get_spender_limits, last_approved,
add_spender_leaf, channel_list, get_accounting_for_channel, get_all_spender_limits,
get_spender_limits, last_approved,
validator_message::{
create_validator_messages, extract_params, list_validator_messages,
},
},
event_aggregate::list_channel_event_aggregates,
validator_message::{extract_params, list_validator_messages},
},
};

pub mod analytics;
pub mod middleware;
pub mod routes {
pub mod analytics;
pub mod campaign;
pub mod cfg;
pub mod channel;
pub mod event_aggregate;
pub mod validator_message;
}

pub mod routes;
pub mod access;
pub mod analytics_recorder;
pub mod application;
pub mod db;
pub mod payout;
Expand All @@ -59,15 +52,12 @@ static LAST_APPROVED_BY_CHANNEL_ID: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"^/v5/channel/0x([a-zA-Z0-9]{64})/last-approved/?$")
.expect("The regex should be valid")
});
// Only the initial Regex to be matched.

/// Only the initial Regex to be matched.
static CHANNEL_VALIDATOR_MESSAGES: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"^/v5/channel/0x([a-zA-Z0-9]{64})/validator-messages(/.*)?$")
.expect("The regex should be valid")
});
static CHANNEL_EVENTS_AGGREGATES: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"^/v5/channel/0x([a-zA-Z0-9]{64})/events-aggregates/?$")
.expect("The regex should be valid")
});
static CHANNEL_SPENDER_LEAF_AND_TOTAL_DEPOSITED: Lazy<Regex> = Lazy::new(|| {
Regex::new(r"^/v5/channel/0x([a-zA-Z0-9]{64})/spender/0x([a-zA-Z0-9]{40})/?$")
.expect("This regex should be valid")
Expand All @@ -91,6 +81,8 @@ static CHANNEL_ACCOUNTING: Lazy<Regex> = Lazy::new(|| {
.expect("The regex should be valid")
});

/// Regex extracted parameters.
/// This struct is created manually on each of the matched routes.
#[derive(Debug, Clone)]
pub struct RouteParams(pub Vec<String>);

Expand All @@ -104,8 +96,7 @@ impl RouteParams {
}
}

// #[derive(Clone)]
// pub struct Application<C: Locked + 'static> {
/// The Sentry REST web application
pub struct Application<C: Locked + 'static> {
/// For sentry to work properly, we need an [`adapter::Adapter`] in a [`adapter::LockedState`] state.
pub adapter: Adapter<C>,
Expand Down Expand Up @@ -152,7 +143,7 @@ where
};

let mut response = match (req.uri().path(), req.method()) {
("/cfg", &Method::GET) => config(req, self).await,
("/cfg", &Method::GET) => get_cfg(req, self).await,
("/channel/list", &Method::GET) => channel_list(req, self).await,
(route, _) if route.starts_with("/analytics") => analytics_router(req, self).await,
// This is important because it prevents us from doing
Expand Down Expand Up @@ -226,7 +217,6 @@ async fn analytics_router<C: Locked + 'static>(
mut req: Request<Body>,
app: &Application<C>,
) -> Result<Response<Body>, ResponseError> {
use routes::analytics::analytics;

let (route, method) = (req.uri().path(), req.method());

Expand All @@ -235,7 +225,7 @@ async fn analytics_router<C: Locked + 'static>(
let allowed_keys_for_request = vec![AllowedKey::Country, AllowedKey::AdSlotType]
.into_iter()
.collect();
analytics(req, app, Some(allowed_keys_for_request), None).await
get_analytics(req, app, Some(allowed_keys_for_request), None).await
}
("/analytics/for-advertiser", &Method::GET) => {
let req = AuthRequired.call(req, app).await?;
Expand All @@ -246,7 +236,7 @@ async fn analytics_router<C: Locked + 'static>(
.map(|auth| AuthenticateAs::Advertiser(auth.uid))
.ok_or(ResponseError::Unauthorized)?;

analytics(req, app, None, Some(authenticate_as)).await
get_analytics(req, app, None, Some(authenticate_as)).await
}
("/analytics/for-publisher", &Method::GET) => {
let authenticate_as = req
Expand All @@ -256,15 +246,15 @@ async fn analytics_router<C: Locked + 'static>(
.ok_or(ResponseError::Unauthorized)?;

let req = AuthRequired.call(req, app).await?;
analytics(req, app, None, Some(authenticate_as)).await
get_analytics(req, app, None, Some(authenticate_as)).await
}
("/analytics/for-admin", &Method::GET) => {
req = Chain::new()
.chain(AuthRequired)
.chain(IsAdmin)
.apply(req, app)
.await?;
analytics(req, app, None, None).await
get_analytics(req, app, None, None).await
}
_ => Err(ResponseError::NotFound),
}
Expand Down Expand Up @@ -328,20 +318,6 @@ async fn channels_router<C: Locked + 'static>(
.await?;

create_validator_messages(req, app).await
} else if let (Some(caps), &Method::GET) = (CHANNEL_EVENTS_AGGREGATES.captures(&path), method) {
req = AuthRequired.call(req, app).await?;

let param = RouteParams(vec![
caps.get(1)
.map_or("".to_string(), |m| m.as_str().to_string()),
caps.get(2)
.map_or("".to_string(), |m| m.as_str().trim_matches('/').to_string()),
]);
req.extensions_mut().insert(param);

req = ChannelLoad.call(req, app).await?;

list_channel_event_aggregates(req, app).await
} else if let (Some(caps), &Method::GET) = (
CHANNEL_SPENDER_LEAF_AND_TOTAL_DEPOSITED.captures(&path),
method,
Expand Down Expand Up @@ -512,7 +488,7 @@ pub fn epoch() -> f64 {
Utc::now().timestamp() as f64 / 2_628_000_000.0
}

// @TODO: Make pub(crate)
/// Sentry [`Application`] Session
#[derive(Debug, Clone)]
pub struct Session {
pub ip: Option<String>,
Expand All @@ -521,6 +497,7 @@ pub struct Session {
pub os: Option<String>,
}

/// Sentry [`Application`] Auth (Authentication)
#[derive(Debug, Clone)]
pub struct Auth {
pub era: i64,
Expand Down
Loading