Skip to content

Commit

Permalink
Merge #1218: Overhaul core Tracker: create dependency containers for …
Browse files Browse the repository at this point in the history
…UDP tracker, HTTP tracker and Tracker API

b38e4af chore: add DevSkim ignore DS173237 (Jose Celano)
66b2b56 refactor: [#1217] extract HttpApiContainer (Jose Celano)
a2bf1cd refactor: [#1217] extract HttpTrackerContainer (Jose Celano)
5342a5d refactor: [#1217] extract UdpTrackerContainer (Jose Celano)

Pull request description:

  Overhaul core Tracker: create dependency containers for UDP tracker, HTTP tracker and Tracker API.

  ### Subtasks

  - [x] Extract `UdpTrackerContainer`
  - [x] Extract `HttpTrackerContainer`
  - [x] Extract `HttpApiContainer`

ACKs for top commit:
  josecelano:
    ACK b38e4af

Tree-SHA512: da14cb884920eaf7f7c249dace05596a61ee0532efb77cb4bd5c381e6c5d2b119d86f8f22764080b84c7f165c4fc524dce2eb4e311521728fdb81d172bda6164
  • Loading branch information
josecelano committed Jan 29, 2025
2 parents b8e0803 + b38e4af commit 46e9d25
Show file tree
Hide file tree
Showing 39 changed files with 485 additions and 932 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ pub async fn run(http_trackers: Vec<Url>, timeout: Duration) -> Vec<Result<Check
}

async fn check_http_announce(url: &Url, timeout: Duration) -> Result<Announce, Error> {
let info_hash_str = "9c38422213e30bff212b30c360d26f9a02136422".to_string(); // # DevSkim: ignore DS173237
let info_hash_str = "9c38422213e30bff212b30c360d26f9a02136422".to_string(); // DevSkim: ignore DS173237
let info_hash = InfoHash::from_str(&info_hash_str).expect("a valid info-hash is required");

let client = Client::new(url.clone(), timeout).map_err(|err| Error::HttpClientError { err })?;
Expand All @@ -86,7 +86,7 @@ async fn check_http_announce(url: &Url, timeout: Duration) -> Result<Announce, E
}

async fn check_http_scrape(url: &Url, timeout: Duration) -> Result<scrape::Response, Error> {
let info_hashes: Vec<String> = vec!["9c38422213e30bff212b30c360d26f9a02136422".to_string()]; // # DevSkim: ignore DS173237
let info_hashes: Vec<String> = vec!["9c38422213e30bff212b30c360d26f9a02136422".to_string()]; // DevSkim: ignore DS173237
let query = requests::scrape::Query::try_from(info_hashes).expect("a valid array of info-hashes is required");

let client = Client::new(url.clone(), timeout).map_err(|err| Error::HttpClientError { err })?;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub async fn run(udp_trackers: Vec<Url>, timeout: Duration) -> Vec<Result<Checks

tracing::debug!("UDP trackers ...");

let info_hash = aquatic_udp_protocol::InfoHash(hex!("9c38422213e30bff212b30c360d26f9a02136422")); // # DevSkim: ignore DS173237
let info_hash = aquatic_udp_protocol::InfoHash(hex!("9c38422213e30bff212b30c360d26f9a02136422")); // DevSkim: ignore DS173237

for remote_url in udp_trackers {
let remote_addr = resolve_socket_addr(&remote_url);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ impl QueryBuilder {
#[must_use]
pub fn with_default_values() -> QueryBuilder {
let default_announce_query = Query {
info_hash: InfoHash::from_str("9c38422213e30bff212b30c360d26f9a02136422").unwrap().0, // # DevSkim: ignore DS173237
info_hash: InfoHash::from_str("9c38422213e30bff212b30c360d26f9a02136422").unwrap().0, // DevSkim: ignore DS173237
peer_addr: IpAddr::V4(Ipv4Addr::new(192, 168, 1, 88)),
downloaded: 0,
uploaded: 0,
Expand Down
2 changes: 1 addition & 1 deletion packages/tracker-client/src/http/client/requests/scrape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ pub struct QueryBuilder {
impl Default for QueryBuilder {
fn default() -> Self {
let default_scrape_query = Query {
info_hash: [InfoHash::from_str("9c38422213e30bff212b30c360d26f9a02136422").unwrap().0].to_vec(), // # DevSkim: ignore DS173237
info_hash: [InfoHash::from_str("9c38422213e30bff212b30c360d26f9a02136422").unwrap().0].to_vec(), // DevSkim: ignore DS173237
};
Self {
scrape_query: default_scrape_query,
Expand Down
55 changes: 15 additions & 40 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use torrust_tracker_configuration::Configuration;
use tracing::instrument;

use crate::bootstrap::jobs::{health_check_api, http_tracker, torrent_cleanup, tracker_apis, udp_tracker};
use crate::container::AppContainer;
use crate::container::{AppContainer, HttpApiContainer, HttpTrackerContainer, UdpTrackerContainer};
use crate::servers;
use crate::servers::registar::Registar;

Expand All @@ -39,7 +39,7 @@ use crate::servers::registar::Registar;
/// - Can't retrieve tracker keys from database.
/// - Can't load whitelist from database.
#[instrument(skip(config, app_container))]
pub async fn start(config: &Configuration, app_container: &AppContainer) -> Vec<JoinHandle<()>> {
pub async fn start(config: &Configuration, app_container: &Arc<AppContainer>) -> Vec<JoinHandle<()>> {
if config.http_api.is_none()
&& (config.udp_trackers.is_none() || config.udp_trackers.as_ref().map_or(true, std::vec::Vec::is_empty))
&& (config.http_trackers.is_none() || config.http_trackers.as_ref().map_or(true, std::vec::Vec::is_empty))
Expand Down Expand Up @@ -78,19 +78,10 @@ pub async fn start(config: &Configuration, app_container: &AppContainer) -> Vec<
udp_tracker_config.bind_address
);
} else {
jobs.push(
udp_tracker::start_job(
Arc::new(config.core.clone()),
udp_tracker_config,
app_container.announce_handler.clone(),
app_container.scrape_handler.clone(),
app_container.whitelist_authorization.clone(),
app_container.stats_event_sender.clone(),
app_container.ban_service.clone(),
registar.give_form(),
)
.await,
);
let udp_tracker_config = Arc::new(udp_tracker_config.clone());
let udp_tracker_container = Arc::new(UdpTrackerContainer::from_app_container(&udp_tracker_config, app_container));

jobs.push(udp_tracker::start_job(udp_tracker_container, registar.give_form()).await);
}
}
} else {
Expand All @@ -100,18 +91,11 @@ pub async fn start(config: &Configuration, app_container: &AppContainer) -> Vec<
// Start the HTTP blocks
if let Some(http_trackers) = &config.http_trackers {
for http_tracker_config in http_trackers {
if let Some(job) = http_tracker::start_job(
http_tracker_config,
Arc::new(config.core.clone()),
app_container.announce_handler.clone(),
app_container.scrape_handler.clone(),
app_container.authentication_service.clone(),
app_container.whitelist_authorization.clone(),
app_container.stats_event_sender.clone(),
registar.give_form(),
servers::http::Version::V1,
)
.await
let http_tracker_config = Arc::new(http_tracker_config.clone());
let http_tracker_container = Arc::new(HttpTrackerContainer::from_app_container(&http_tracker_config, app_container));

if let Some(job) =
http_tracker::start_job(http_tracker_container, registar.give_form(), servers::http::Version::V1).await
{
jobs.push(job);
};
Expand All @@ -122,19 +106,10 @@ pub async fn start(config: &Configuration, app_container: &AppContainer) -> Vec<

// Start HTTP API
if let Some(http_api_config) = &config.http_api {
if let Some(job) = tracker_apis::start_job(
http_api_config,
app_container.in_memory_torrent_repository.clone(),
app_container.keys_handler.clone(),
app_container.whitelist_manager.clone(),
app_container.ban_service.clone(),
app_container.stats_event_sender.clone(),
app_container.stats_repository.clone(),
registar.give_form(),
servers::apis::Version::V1,
)
.await
{
let http_api_config = Arc::new(http_api_config.clone());
let http_api_container = Arc::new(HttpApiContainer::from_app_container(&http_api_config, app_container));

if let Some(job) = tracker_apis::start_job(http_api_container, registar.give_form(), servers::apis::Version::V1).await {
jobs.push(job);
};
} else {
Expand Down
9 changes: 4 additions & 5 deletions src/bootstrap/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use crate::core::services::{initialize_database, initialize_whitelist_manager, s
use crate::core::torrent::manager::TorrentsManager;
use crate::core::torrent::repository::in_memory::InMemoryTorrentRepository;
use crate::core::torrent::repository::persisted::DatabasePersistentTorrentRepository;
use crate::core::whitelist;
use crate::core::whitelist::authorization::WhitelistAuthorization;
use crate::core::whitelist::repository::in_memory::InMemoryWhitelist;
use crate::servers::udp::server::banning::BanService;
use crate::servers::udp::server::launcher::MAX_CONNECTION_ID_ERRORS_PER_IP;
Expand Down Expand Up @@ -87,16 +87,14 @@ pub fn initialize_global_services(configuration: &Configuration) {
/// It initializes the IoC Container.
#[instrument(skip())]
pub fn initialize_app_container(configuration: &Configuration) -> AppContainer {
let core_config = Arc::new(configuration.core.clone());
let (stats_event_sender, stats_repository) = statistics::setup::factory(configuration.core.tracker_usage_statistics);
let stats_event_sender = Arc::new(stats_event_sender);
let stats_repository = Arc::new(stats_repository);
let ban_service = Arc::new(RwLock::new(BanService::new(MAX_CONNECTION_ID_ERRORS_PER_IP)));
let database = initialize_database(configuration);
let in_memory_whitelist = Arc::new(InMemoryWhitelist::default());
let whitelist_authorization = Arc::new(whitelist::authorization::WhitelistAuthorization::new(
&configuration.core,
&in_memory_whitelist.clone(),
));
let whitelist_authorization = Arc::new(WhitelistAuthorization::new(&configuration.core, &in_memory_whitelist.clone()));
let whitelist_manager = initialize_whitelist_manager(database.clone(), in_memory_whitelist.clone());
let db_key_repository = Arc::new(DatabaseKeyRepository::new(&database));
let in_memory_key_repository = Arc::new(InMemoryKeyRepository::default());
Expand Down Expand Up @@ -125,6 +123,7 @@ pub fn initialize_app_container(configuration: &Configuration) -> AppContainer {
let scrape_handler = Arc::new(ScrapeHandler::new(&whitelist_authorization, &in_memory_torrent_repository));

AppContainer {
core_config,
database,
announce_handler,
scrape_handler,
Expand Down
96 changes: 17 additions & 79 deletions src/bootstrap/jobs/http_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,10 @@ use std::sync::Arc;

use axum_server::tls_rustls::RustlsConfig;
use tokio::task::JoinHandle;
use torrust_tracker_configuration::{Core, HttpTracker};
use tracing::instrument;

use super::make_rust_tls;
use crate::core::announce_handler::AnnounceHandler;
use crate::core::authentication::service::AuthenticationService;
use crate::core::scrape_handler::ScrapeHandler;
use crate::core::statistics::event::sender::Sender;
use crate::core::{statistics, whitelist};
use crate::container::HttpTrackerContainer;
use crate::servers::http::server::{HttpServer, Launcher};
use crate::servers::http::Version;
use crate::servers::registar::ServiceRegistrationForm;
Expand All @@ -36,83 +31,33 @@ use crate::servers::registar::ServiceRegistrationForm;
/// # Panics
///
/// It would panic if the `config::HttpTracker` struct would contain inappropriate values.
#[allow(clippy::too_many_arguments)]
#[instrument(skip(
config,
announce_handler,
scrape_handler,
authentication_service,
whitelist_authorization,
stats_event_sender,
form
))]
#[instrument(skip(http_tracker_container, form))]
pub async fn start_job(
config: &HttpTracker,
core_config: Arc<Core>,
announce_handler: Arc<AnnounceHandler>,
scrape_handler: Arc<ScrapeHandler>,
authentication_service: Arc<AuthenticationService>,
whitelist_authorization: Arc<whitelist::authorization::WhitelistAuthorization>,
stats_event_sender: Arc<Option<Box<dyn Sender>>>,
http_tracker_container: Arc<HttpTrackerContainer>,
form: ServiceRegistrationForm,
version: Version,
) -> Option<JoinHandle<()>> {
let socket = config.bind_address;
let socket = http_tracker_container.http_tracker_config.bind_address;

let tls = make_rust_tls(&config.tsl_config)
let tls = make_rust_tls(&http_tracker_container.http_tracker_config.tsl_config)
.await
.map(|tls| tls.expect("it should have a valid http tracker tls configuration"));

match version {
Version::V1 => Some(
start_v1(
socket,
tls,
core_config.clone(),
announce_handler.clone(),
scrape_handler.clone(),
authentication_service.clone(),
whitelist_authorization.clone(),
stats_event_sender.clone(),
form,
)
.await,
),
Version::V1 => Some(start_v1(socket, tls, http_tracker_container, form).await),
}
}

#[allow(clippy::too_many_arguments)]
#[allow(clippy::async_yields_async)]
#[instrument(skip(
socket,
tls,
announce_handler,
scrape_handler,
whitelist_authorization,
stats_event_sender,
form
))]
#[instrument(skip(socket, tls, http_tracker_container, form))]
async fn start_v1(
socket: SocketAddr,
tls: Option<RustlsConfig>,
config: Arc<Core>,
announce_handler: Arc<AnnounceHandler>,
scrape_handler: Arc<ScrapeHandler>,
authentication_service: Arc<AuthenticationService>,
whitelist_authorization: Arc<whitelist::authorization::WhitelistAuthorization>,
stats_event_sender: Arc<Option<Box<dyn statistics::event::sender::Sender>>>,
http_tracker_container: Arc<HttpTrackerContainer>,
form: ServiceRegistrationForm,
) -> JoinHandle<()> {
let server = HttpServer::new(Launcher::new(socket, tls))
.start(
config,
announce_handler,
scrape_handler,
authentication_service,
whitelist_authorization,
stats_event_sender,
form,
)
.start(http_tracker_container, form)
.await
.expect("it should be able to start to the http tracker");

Expand All @@ -137,33 +82,26 @@ mod tests {

use crate::bootstrap::app::{initialize_app_container, initialize_global_services};
use crate::bootstrap::jobs::http_tracker::start_job;
use crate::container::HttpTrackerContainer;
use crate::servers::http::Version;
use crate::servers::registar::Registar;

#[tokio::test]
async fn it_should_start_http_tracker() {
let cfg = Arc::new(ephemeral_public());
let http_tracker = cfg.http_trackers.clone().expect("missing HTTP tracker configuration");
let config = &http_tracker[0];
let http_tracker_config = Arc::new(http_tracker[0].clone());

initialize_global_services(&cfg);

let app_container = initialize_app_container(&cfg);
let app_container = Arc::new(initialize_app_container(&cfg));

let http_tracker_container = Arc::new(HttpTrackerContainer::from_app_container(&http_tracker_config, &app_container));

let version = Version::V1;

start_job(
config,
Arc::new(cfg.core.clone()),
app_container.announce_handler,
app_container.scrape_handler,
app_container.authentication_service,
app_container.whitelist_authorization,
app_container.stats_event_sender,
Registar::default().give_form(),
version,
)
.await
.expect("it should be able to join to the http tracker start-job");
start_job(http_tracker_container, Registar::default().give_form(), version)
.await
.expect("it should be able to join to the http tracker start-job");
}
}
Loading

0 comments on commit 46e9d25

Please sign in to comment.