Skip to content

Commit 203ce96

Browse files
committed
Merge #623: Extract Config from Tracker and Heath Check
3f0dcea dev: add tests to health check (Cameron Garnham) b310c75 dev: extract config from health check (Cameron Garnham) 3b49257 dev: extract config from core::tracker (Cameron Garnham) Pull request description: This is the first three commits from #557 It includes an significant improvement of the Heath Check logic, as it now takes the active port from the binding, instead of the configuration. ACKs for top commit: josecelano: ACK 3f0dcea Tree-SHA512: 5076583618bf68dd7fe016b55da5a14490be2ec4e3416efe7d3bcd27c73fedbe5a219cd9f5bcc62c526007d1ae17fab7323b2199aa14fd9542bbe52eba2b6b38
2 parents dde3d8d + 3f0dcea commit 203ce96

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1720
-1274
lines changed

cSpell.json

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
"Cyberneering",
3535
"datagram",
3636
"datetime",
37+
"Deque",
3738
"Dijke",
3839
"distroless",
3940
"dockerhub",
@@ -91,6 +92,7 @@
9192
"Rasterbar",
9293
"realpath",
9394
"reannounce",
95+
"Registar",
9496
"repr",
9597
"reqwest",
9698
"rerequests",

packages/configuration/src/lib.rs

+6-12
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@
229229
//! [health_check_api]
230230
//! bind_address = "127.0.0.1:1313"
231231
//!```
232-
use std::collections::{HashMap, HashSet};
232+
use std::collections::HashMap;
233233
use std::net::IpAddr;
234234
use std::str::FromStr;
235235
use std::sync::Arc;
@@ -337,6 +337,8 @@ pub struct HttpTracker {
337337
pub ssl_key_path: Option<String>,
338338
}
339339

340+
pub type AccessTokens = HashMap<String, String>;
341+
340342
/// Configuration for the HTTP API.
341343
#[serde_as]
342344
#[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
@@ -360,21 +362,13 @@ pub struct HttpApi {
360362
/// token and the value is the token itself. The token is used to
361363
/// authenticate the user. All tokens are valid for all endpoints and have
362364
/// the all permissions.
363-
pub access_tokens: HashMap<String, String>,
365+
pub access_tokens: AccessTokens,
364366
}
365367

366368
impl HttpApi {
367369
fn override_admin_token(&mut self, api_admin_token: &str) {
368370
self.access_tokens.insert("admin".to_string(), api_admin_token.to_string());
369371
}
370-
371-
/// Checks if the given token is one of the token in the configuration.
372-
#[must_use]
373-
pub fn contains_token(&self, token: &str) -> bool {
374-
let tokens: HashMap<String, String> = self.access_tokens.clone();
375-
let tokens: HashSet<String> = tokens.into_values().collect();
376-
tokens.contains(token)
377-
}
378372
}
379373

380374
/// Configuration for the Health Check API.
@@ -804,7 +798,7 @@ mod tests {
804798
fn http_api_configuration_should_check_if_it_contains_a_token() {
805799
let configuration = Configuration::default();
806800

807-
assert!(configuration.http_api.contains_token("MyAccessToken"));
808-
assert!(!configuration.http_api.contains_token("NonExistingToken"));
801+
assert!(configuration.http_api.access_tokens.values().any(|t| t == "MyAccessToken"));
802+
assert!(!configuration.http_api.access_tokens.values().any(|t| t == "NonExistingToken"));
809803
}
810804
}

src/app.rs

+23-6
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use tokio::task::JoinHandle;
2828
use torrust_tracker_configuration::Configuration;
2929

3030
use crate::bootstrap::jobs::{health_check_api, http_tracker, torrent_cleanup, tracker_apis, udp_tracker};
31+
use crate::servers::registar::Registar;
3132
use crate::{core, servers};
3233

3334
/// # Panics
@@ -36,9 +37,11 @@ use crate::{core, servers};
3637
///
3738
/// - Can't retrieve tracker keys from database.
3839
/// - Can't load whitelist from database.
39-
pub async fn start(config: Arc<Configuration>, tracker: Arc<core::Tracker>) -> Vec<JoinHandle<()>> {
40+
pub async fn start(config: &Configuration, tracker: Arc<core::Tracker>) -> Vec<JoinHandle<()>> {
4041
let mut jobs: Vec<JoinHandle<()>> = Vec::new();
4142

43+
let registar = Registar::default();
44+
4245
// Load peer keys
4346
if tracker.is_private() {
4447
tracker
@@ -67,31 +70,45 @@ pub async fn start(config: Arc<Configuration>, tracker: Arc<core::Tracker>) -> V
6770
udp_tracker_config.bind_address, config.mode
6871
);
6972
} else {
70-
jobs.push(udp_tracker::start_job(udp_tracker_config, tracker.clone()).await);
73+
jobs.push(udp_tracker::start_job(udp_tracker_config, tracker.clone(), registar.give_form()).await);
7174
}
7275
}
7376

7477
// Start the HTTP blocks
7578
for http_tracker_config in &config.http_trackers {
76-
if let Some(job) = http_tracker::start_job(http_tracker_config, tracker.clone(), servers::http::Version::V1).await {
79+
if let Some(job) = http_tracker::start_job(
80+
http_tracker_config,
81+
tracker.clone(),
82+
registar.give_form(),
83+
servers::http::Version::V1,
84+
)
85+
.await
86+
{
7787
jobs.push(job);
7888
};
7989
}
8090

8191
// Start HTTP API
8292
if config.http_api.enabled {
83-
if let Some(job) = tracker_apis::start_job(&config.http_api, tracker.clone(), servers::apis::Version::V1).await {
93+
if let Some(job) = tracker_apis::start_job(
94+
&config.http_api,
95+
tracker.clone(),
96+
registar.give_form(),
97+
servers::apis::Version::V1,
98+
)
99+
.await
100+
{
84101
jobs.push(job);
85102
};
86103
}
87104

88105
// Start runners to remove torrents without peers, every interval
89106
if config.inactive_peer_cleanup_interval > 0 {
90-
jobs.push(torrent_cleanup::start_job(&config, &tracker));
107+
jobs.push(torrent_cleanup::start_job(config, &tracker));
91108
}
92109

93110
// Start Health Check API
94-
jobs.push(health_check_api::start_job(config).await);
111+
jobs.push(health_check_api::start_job(&config.health_check_api, registar.entries()).await);
95112

96113
jobs
97114
}

src/bootstrap/app.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ use crate::shared::crypto::ephemeral_instance_keys;
2424

2525
/// It loads the configuration from the environment and builds the main domain [`Tracker`] struct.
2626
#[must_use]
27-
pub fn setup() -> (Arc<Configuration>, Arc<Tracker>) {
28-
let configuration = Arc::new(initialize_configuration());
27+
pub fn setup() -> (Configuration, Arc<Tracker>) {
28+
let configuration = initialize_configuration();
2929
let tracker = initialize_with_configuration(&configuration);
3030

3131
(configuration, tracker)
@@ -35,7 +35,7 @@ pub fn setup() -> (Arc<Configuration>, Arc<Tracker>) {
3535
///
3636
/// The configuration may be obtained from the environment (via config file or env vars).
3737
#[must_use]
38-
pub fn initialize_with_configuration(configuration: &Arc<Configuration>) -> Arc<Tracker> {
38+
pub fn initialize_with_configuration(configuration: &Configuration) -> Arc<Tracker> {
3939
initialize_static();
4040
initialize_logging(configuration);
4141
Arc::new(initialize_tracker(configuration))
@@ -60,13 +60,13 @@ pub fn initialize_static() {
6060
/// The tracker is the domain layer service. It's the entrypoint to make requests to the domain layer.
6161
/// It's used by other higher-level components like the UDP and HTTP trackers or the tracker API.
6262
#[must_use]
63-
pub fn initialize_tracker(config: &Arc<Configuration>) -> Tracker {
64-
tracker_factory(config.clone())
63+
pub fn initialize_tracker(config: &Configuration) -> Tracker {
64+
tracker_factory(config)
6565
}
6666

6767
/// It initializes the log level, format and channel.
6868
///
6969
/// See [the logging setup](crate::bootstrap::logging::setup) for more info about logging.
70-
pub fn initialize_logging(config: &Arc<Configuration>) {
70+
pub fn initialize_logging(config: &Configuration) {
7171
bootstrap::logging::setup(config);
7272
}

src/bootstrap/jobs/health_check_api.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,16 @@
1313
//!
1414
//! Refer to the [configuration documentation](https://docs.rs/torrust-tracker-configuration)
1515
//! for the API configuration options.
16-
use std::sync::Arc;
1716
1817
use log::info;
1918
use tokio::sync::oneshot;
2019
use tokio::task::JoinHandle;
21-
use torrust_tracker_configuration::Configuration;
20+
use torrust_tracker_configuration::HealthCheckApi;
2221

2322
use super::Started;
2423
use crate::servers::health_check_api::server;
24+
use crate::servers::registar::ServiceRegistry;
25+
use crate::servers::signals::Halted;
2526

2627
/// This function starts a new Health Check API server with the provided
2728
/// configuration.
@@ -33,20 +34,21 @@ use crate::servers::health_check_api::server;
3334
/// # Panics
3435
///
3536
/// It would panic if unable to send the `ApiServerJobStarted` notice.
36-
pub async fn start_job(config: Arc<Configuration>) -> JoinHandle<()> {
37+
pub async fn start_job(config: &HealthCheckApi, register: ServiceRegistry) -> JoinHandle<()> {
3738
let bind_addr = config
38-
.health_check_api
3939
.bind_address
4040
.parse::<std::net::SocketAddr>()
4141
.expect("it should have a valid health check bind address");
4242

4343
let (tx_start, rx_start) = oneshot::channel::<Started>();
44+
let (tx_halt, rx_halt) = tokio::sync::oneshot::channel::<Halted>();
45+
drop(tx_halt);
4446

4547
// Run the API server
4648
let join_handle = tokio::spawn(async move {
4749
info!(target: "Health Check API", "Starting on: http://{}", bind_addr);
4850

49-
let handle = server::start(bind_addr, tx_start, config.clone());
51+
let handle = server::start(bind_addr, tx_start, rx_halt, register);
5052

5153
if let Ok(()) = handle.await {
5254
info!(target: "Health Check API", "Stopped server running on: http://{}", bind_addr);

src/bootstrap/jobs/http_tracker.rs

+17-5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use super::make_rust_tls;
2222
use crate::core;
2323
use crate::servers::http::server::{HttpServer, Launcher};
2424
use crate::servers::http::Version;
25+
use crate::servers::registar::ServiceRegistrationForm;
2526

2627
/// It starts a new HTTP server with the provided configuration and version.
2728
///
@@ -32,7 +33,12 @@ use crate::servers::http::Version;
3233
///
3334
/// It would panic if the `config::HttpTracker` struct would contain inappropriate values.
3435
///
35-
pub async fn start_job(config: &HttpTracker, tracker: Arc<core::Tracker>, version: Version) -> Option<JoinHandle<()>> {
36+
pub async fn start_job(
37+
config: &HttpTracker,
38+
tracker: Arc<core::Tracker>,
39+
form: ServiceRegistrationForm,
40+
version: Version,
41+
) -> Option<JoinHandle<()>> {
3642
if config.enabled {
3743
let socket = config
3844
.bind_address
@@ -44,17 +50,22 @@ pub async fn start_job(config: &HttpTracker, tracker: Arc<core::Tracker>, versio
4450
.map(|tls| tls.expect("it should have a valid http tracker tls configuration"));
4551

4652
match version {
47-
Version::V1 => Some(start_v1(socket, tls, tracker.clone()).await),
53+
Version::V1 => Some(start_v1(socket, tls, tracker.clone(), form).await),
4854
}
4955
} else {
5056
info!("Note: Not loading Http Tracker Service, Not Enabled in Configuration.");
5157
None
5258
}
5359
}
5460

55-
async fn start_v1(socket: SocketAddr, tls: Option<RustlsConfig>, tracker: Arc<core::Tracker>) -> JoinHandle<()> {
61+
async fn start_v1(
62+
socket: SocketAddr,
63+
tls: Option<RustlsConfig>,
64+
tracker: Arc<core::Tracker>,
65+
form: ServiceRegistrationForm,
66+
) -> JoinHandle<()> {
5667
let server = HttpServer::new(Launcher::new(socket, tls))
57-
.start(tracker)
68+
.start(tracker, form)
5869
.await
5970
.expect("it should be able to start to the http tracker");
6071

@@ -80,6 +91,7 @@ mod tests {
8091
use crate::bootstrap::app::initialize_with_configuration;
8192
use crate::bootstrap::jobs::http_tracker::start_job;
8293
use crate::servers::http::Version;
94+
use crate::servers::registar::Registar;
8395

8496
#[tokio::test]
8597
async fn it_should_start_http_tracker() {
@@ -88,7 +100,7 @@ mod tests {
88100
let tracker = initialize_with_configuration(&cfg);
89101
let version = Version::V1;
90102

91-
start_job(config, tracker, version)
103+
start_job(config, tracker, Registar::default().give_form(), version)
92104
.await
93105
.expect("it should be able to join to the http tracker start-job");
94106
}

src/bootstrap/jobs/torrent_cleanup.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use crate::core;
2525
///
2626
/// Refer to [`torrust-tracker-configuration documentation`](https://docs.rs/torrust-tracker-configuration) for more info about that option.
2727
#[must_use]
28-
pub fn start_job(config: &Arc<Configuration>, tracker: &Arc<core::Tracker>) -> JoinHandle<()> {
28+
pub fn start_job(config: &Configuration, tracker: &Arc<core::Tracker>) -> JoinHandle<()> {
2929
let weak_tracker = std::sync::Arc::downgrade(tracker);
3030
let interval = config.inactive_peer_cleanup_interval;
3131

src/bootstrap/jobs/tracker_apis.rs

+21-6
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,13 @@ use std::sync::Arc;
2626
use axum_server::tls_rustls::RustlsConfig;
2727
use log::info;
2828
use tokio::task::JoinHandle;
29-
use torrust_tracker_configuration::HttpApi;
29+
use torrust_tracker_configuration::{AccessTokens, HttpApi};
3030

3131
use super::make_rust_tls;
3232
use crate::core;
3333
use crate::servers::apis::server::{ApiServer, Launcher};
3434
use crate::servers::apis::Version;
35+
use crate::servers::registar::ServiceRegistrationForm;
3536

3637
/// This is the message that the "launcher" spawned task sends to the main
3738
/// application process to notify the API server was successfully started.
@@ -53,7 +54,12 @@ pub struct ApiServerJobStarted();
5354
/// It would panic if unable to send the `ApiServerJobStarted` notice.
5455
///
5556
///
56-
pub async fn start_job(config: &HttpApi, tracker: Arc<core::Tracker>, version: Version) -> Option<JoinHandle<()>> {
57+
pub async fn start_job(
58+
config: &HttpApi,
59+
tracker: Arc<core::Tracker>,
60+
form: ServiceRegistrationForm,
61+
version: Version,
62+
) -> Option<JoinHandle<()>> {
5763
if config.enabled {
5864
let bind_to = config
5965
.bind_address
@@ -64,18 +70,26 @@ pub async fn start_job(config: &HttpApi, tracker: Arc<core::Tracker>, version: V
6470
.await
6571
.map(|tls| tls.expect("it should have a valid tracker api tls configuration"));
6672

73+
let access_tokens = Arc::new(config.access_tokens.clone());
74+
6775
match version {
68-
Version::V1 => Some(start_v1(bind_to, tls, tracker.clone()).await),
76+
Version::V1 => Some(start_v1(bind_to, tls, tracker.clone(), form, access_tokens).await),
6977
}
7078
} else {
7179
info!("Note: Not loading Http Tracker Service, Not Enabled in Configuration.");
7280
None
7381
}
7482
}
7583

76-
async fn start_v1(socket: SocketAddr, tls: Option<RustlsConfig>, tracker: Arc<core::Tracker>) -> JoinHandle<()> {
84+
async fn start_v1(
85+
socket: SocketAddr,
86+
tls: Option<RustlsConfig>,
87+
tracker: Arc<core::Tracker>,
88+
form: ServiceRegistrationForm,
89+
access_tokens: Arc<AccessTokens>,
90+
) -> JoinHandle<()> {
7791
let server = ApiServer::new(Launcher::new(socket, tls))
78-
.start(tracker)
92+
.start(tracker, form, access_tokens)
7993
.await
8094
.expect("it should be able to start to the tracker api");
8195

@@ -94,6 +108,7 @@ mod tests {
94108
use crate::bootstrap::app::initialize_with_configuration;
95109
use crate::bootstrap::jobs::tracker_apis::start_job;
96110
use crate::servers::apis::Version;
111+
use crate::servers::registar::Registar;
97112

98113
#[tokio::test]
99114
async fn it_should_start_http_tracker() {
@@ -102,7 +117,7 @@ mod tests {
102117
let tracker = initialize_with_configuration(&cfg);
103118
let version = Version::V1;
104119

105-
start_job(config, tracker, version)
120+
start_job(config, tracker, Registar::default().give_form(), version)
106121
.await
107122
.expect("it should be able to join to the tracker api start-job");
108123
}

src/bootstrap/jobs/udp_tracker.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use tokio::task::JoinHandle;
1313
use torrust_tracker_configuration::UdpTracker;
1414

1515
use crate::core;
16+
use crate::servers::registar::ServiceRegistrationForm;
1617
use crate::servers::udp::server::{Launcher, UdpServer};
1718

1819
/// It starts a new UDP server with the provided configuration.
@@ -25,14 +26,14 @@ use crate::servers::udp::server::{Launcher, UdpServer};
2526
/// It will panic if it is unable to start the UDP service.
2627
/// It will panic if the task did not finish successfully.
2728
#[must_use]
28-
pub async fn start_job(config: &UdpTracker, tracker: Arc<core::Tracker>) -> JoinHandle<()> {
29+
pub async fn start_job(config: &UdpTracker, tracker: Arc<core::Tracker>, form: ServiceRegistrationForm) -> JoinHandle<()> {
2930
let bind_to = config
3031
.bind_address
3132
.parse::<std::net::SocketAddr>()
3233
.expect("it should have a valid udp tracker bind address");
3334

3435
let server = UdpServer::new(Launcher::new(bind_to))
35-
.start(tracker)
36+
.start(tracker, form)
3637
.await
3738
.expect("it should be able to start the udp tracker");
3839

0 commit comments

Comments
 (0)