diff --git a/src/app.rs b/src/app.rs index c71237443..67a319549 100644 --- a/src/app.rs +++ b/src/app.rs @@ -118,7 +118,7 @@ pub async fn start(config: &Configuration, app_container: &AppContainer) -> Vec< if let Some(http_api_config) = &config.http_api { if let Some(job) = tracker_apis::start_job( http_api_config, - app_container.tracker.clone(), + app_container.in_memory_torrent_repository.clone(), app_container.keys_handler.clone(), app_container.whitelist_manager.clone(), app_container.ban_service.clone(), diff --git a/src/bootstrap/jobs/tracker_apis.rs b/src/bootstrap/jobs/tracker_apis.rs index 1047fa418..f735bc4d7 100644 --- a/src/bootstrap/jobs/tracker_apis.rs +++ b/src/bootstrap/jobs/tracker_apis.rs @@ -33,8 +33,8 @@ use super::make_rust_tls; use crate::core::authentication::handler::KeysHandler; use crate::core::statistics::event::sender::Sender; use crate::core::statistics::repository::Repository; +use crate::core::torrent::repository::in_memory::InMemoryTorrentRepository; use crate::core::whitelist::manager::WhiteListManager; -use crate::core::{self}; use crate::servers::apis::server::{ApiServer, Launcher}; use crate::servers::apis::Version; use crate::servers::registar::ServiceRegistrationForm; @@ -63,7 +63,6 @@ pub struct ApiServerJobStarted(); #[allow(clippy::too_many_arguments)] #[instrument(skip( config, - tracker, keys_handler, whitelist_manager, ban_service, @@ -73,7 +72,7 @@ pub struct ApiServerJobStarted(); ))] pub async fn start_job( config: &HttpApi, - tracker: Arc, + in_memory_torrent_repository: Arc, keys_handler: Arc, whitelist_manager: Arc, ban_service: Arc>, @@ -95,7 +94,7 @@ pub async fn start_job( start_v1( bind_to, tls, - tracker.clone(), + in_memory_torrent_repository.clone(), keys_handler.clone(), whitelist_manager.clone(), ban_service.clone(), @@ -114,7 +113,6 @@ pub async fn start_job( #[instrument(skip( socket, tls, - tracker, keys_handler, whitelist_manager, ban_service, @@ -126,7 +124,7 @@ pub async fn start_job( async fn start_v1( socket: SocketAddr, tls: Option, - tracker: Arc, + in_memory_torrent_repository: Arc, keys_handler: Arc, whitelist_manager: Arc, ban_service: Arc>, @@ -137,7 +135,7 @@ async fn start_v1( ) -> JoinHandle<()> { let server = ApiServer::new(Launcher::new(socket, tls)) .start( - tracker, + in_memory_torrent_repository, keys_handler, whitelist_manager, stats_event_sender, @@ -179,7 +177,7 @@ mod tests { start_job( config, - app_container.tracker, + app_container.in_memory_torrent_repository, app_container.keys_handler, app_container.whitelist_manager, app_container.ban_service, diff --git a/src/core/mod.rs b/src/core/mod.rs index d6d079cf6..6ad48289f 100644 --- a/src/core/mod.rs +++ b/src/core/mod.rs @@ -474,10 +474,10 @@ pub struct Tracker { config: Core, /// The service to check is a torrent is whitelisted. - pub whitelist_authorization: Arc, + whitelist_authorization: Arc, /// The in-memory torrents repository. - pub in_memory_torrent_repository: Arc, + in_memory_torrent_repository: Arc, /// The persistent torrents repository. db_torrent_repository: Arc, @@ -1325,24 +1325,24 @@ mod tests { #[tokio::test] async fn it_should_authorize_the_announce_and_scrape_actions_on_whitelisted_torrents() { - let (tracker, _whitelist_authorization, whitelist_manager) = whitelisted_tracker(); + let (_tracker, whitelist_authorization, whitelist_manager) = whitelisted_tracker(); let info_hash = sample_info_hash(); let result = whitelist_manager.add_torrent_to_whitelist(&info_hash).await; assert!(result.is_ok()); - let result = tracker.whitelist_authorization.authorize(&info_hash).await; + let result = whitelist_authorization.authorize(&info_hash).await; assert!(result.is_ok()); } #[tokio::test] async fn it_should_not_authorize_the_announce_and_scrape_actions_on_not_whitelisted_torrents() { - let (tracker, _whitelist_authorization, _whitelist_manager) = whitelisted_tracker(); + let (_tracker, whitelist_authorization, _whitelist_manager) = whitelisted_tracker(); let info_hash = sample_info_hash(); - let result = tracker.whitelist_authorization.authorize(&info_hash).await; + let result = whitelist_authorization.authorize(&info_hash).await; assert!(result.is_err()); } } diff --git a/src/core/services/statistics/mod.rs b/src/core/services/statistics/mod.rs index fefe17933..ea7ebe994 100644 --- a/src/core/services/statistics/mod.rs +++ b/src/core/services/statistics/mod.rs @@ -45,7 +45,7 @@ use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics; use crate::core::statistics::metrics::Metrics; use crate::core::statistics::repository::Repository; -use crate::core::Tracker; +use crate::core::torrent::repository::in_memory::InMemoryTorrentRepository; use crate::servers::udp::server::banning::BanService; /// All the metrics collected by the tracker. @@ -64,11 +64,11 @@ pub struct TrackerMetrics { /// It returns all the [`TrackerMetrics`] pub async fn get_metrics( - tracker: Arc, + in_memory_torrent_repository: Arc, ban_service: Arc>, stats_repository: Arc, ) -> TrackerMetrics { - let torrents_metrics = tracker.in_memory_torrent_repository.get_torrents_metrics(); + let torrents_metrics = in_memory_torrent_repository.get_torrents_metrics(); let stats = stats_repository.get_stats().await; let udp_banned_ips_total = ban_service.read().await.get_banned_ips_total(); @@ -145,7 +145,7 @@ mod tests { let (_stats_event_sender, stats_repository) = statistics::setup::factory(config.core.tracker_usage_statistics); let stats_repository = Arc::new(stats_repository); - let tracker = Arc::new(initialize_tracker( + let _tracker = Arc::new(initialize_tracker( &config, &whitelist_authorization, &in_memory_torrent_repository, @@ -154,7 +154,12 @@ mod tests { let ban_service = Arc::new(RwLock::new(BanService::new(MAX_CONNECTION_ID_ERRORS_PER_IP))); - let tracker_metrics = get_metrics(tracker.clone(), ban_service.clone(), stats_repository.clone()).await; + let tracker_metrics = get_metrics( + in_memory_torrent_repository.clone(), + ban_service.clone(), + stats_repository.clone(), + ) + .await; assert_eq!( tracker_metrics, diff --git a/src/core/services/torrent.rs b/src/core/services/torrent.rs index c2ffa05aa..dae619d62 100644 --- a/src/core/services/torrent.rs +++ b/src/core/services/torrent.rs @@ -11,7 +11,7 @@ use torrust_tracker_primitives::pagination::Pagination; use torrust_tracker_primitives::peer; use torrust_tracker_torrent_repository::entry::EntrySync; -use crate::core::Tracker; +use crate::core::torrent::repository::in_memory::InMemoryTorrentRepository; /// It contains all the information the tracker has about a torrent #[derive(Debug, PartialEq)] @@ -44,8 +44,11 @@ pub struct BasicInfo { } /// It returns all the information the tracker has about one torrent in a [Info] struct. -pub async fn get_torrent_info(tracker: Arc, info_hash: &InfoHash) -> Option { - let torrent_entry_option = tracker.in_memory_torrent_repository.get(info_hash); +pub async fn get_torrent_info( + in_memory_torrent_repository: Arc, + info_hash: &InfoHash, +) -> Option { + let torrent_entry_option = in_memory_torrent_repository.get(info_hash); let torrent_entry = torrent_entry_option?; @@ -65,10 +68,13 @@ pub async fn get_torrent_info(tracker: Arc, info_hash: &InfoHash) -> Op } /// It returns all the information the tracker has about multiple torrents in a [`BasicInfo`] struct, excluding the peer list. -pub async fn get_torrents_page(tracker: Arc, pagination: Option<&Pagination>) -> Vec { +pub async fn get_torrents_page( + in_memory_torrent_repository: Arc, + pagination: Option<&Pagination>, +) -> Vec { let mut basic_infos: Vec = vec![]; - for (info_hash, torrent_entry) in tracker.in_memory_torrent_repository.get_paginated(pagination) { + for (info_hash, torrent_entry) in in_memory_torrent_repository.get_paginated(pagination) { let stats = torrent_entry.get_swarm_metadata(); basic_infos.push(BasicInfo { @@ -83,15 +89,14 @@ pub async fn get_torrents_page(tracker: Arc, pagination: Option<&Pagina } /// It returns all the information the tracker has about multiple torrents in a [`BasicInfo`] struct, excluding the peer list. -pub async fn get_torrents(tracker: Arc, info_hashes: &[InfoHash]) -> Vec { +pub async fn get_torrents( + in_memory_torrent_repository: Arc, + info_hashes: &[InfoHash], +) -> Vec { let mut basic_infos: Vec = vec![]; for info_hash in info_hashes { - if let Some(stats) = tracker - .in_memory_torrent_repository - .get(info_hash) - .map(|t| t.get_swarm_metadata()) - { + if let Some(stats) = in_memory_torrent_repository.get(info_hash).map(|t| t.get_swarm_metadata()) { basic_infos.push(BasicInfo { info_hash: *info_hash, seeders: u64::from(stats.complete), @@ -115,9 +120,10 @@ mod tests { use crate::app_test::initialize_tracker_dependencies; use crate::core::services::initialize_tracker; + use crate::core::torrent::repository::in_memory::InMemoryTorrentRepository; use crate::core::Tracker; - fn initialize_tracker_and_deps(config: &Configuration) -> Arc { + fn initialize_tracker_and_deps(config: &Configuration) -> (Arc, Arc) { let ( _database, _in_memory_whitelist, @@ -128,12 +134,14 @@ mod tests { _torrents_manager, ) = initialize_tracker_dependencies(config); - Arc::new(initialize_tracker( + let tracker = Arc::new(initialize_tracker( config, &whitelist_authorization, &in_memory_torrent_repository, &db_torrent_repository, - )) + )); + + (tracker, in_memory_torrent_repository) } fn sample_peer() -> peer::Peer { @@ -157,10 +165,9 @@ mod tests { use torrust_tracker_configuration::Configuration; use torrust_tracker_test_helpers::configuration; - use crate::app_test::initialize_tracker_dependencies; - use crate::core::services::initialize_tracker; use crate::core::services::torrent::tests::{initialize_tracker_and_deps, sample_peer}; use crate::core::services::torrent::{get_torrent_info, Info}; + use crate::core::torrent::repository::in_memory::InMemoryTorrentRepository; pub fn tracker_configuration() -> Configuration { configuration::ephemeral() @@ -168,29 +175,10 @@ mod tests { #[tokio::test] async fn should_return_none_if_the_tracker_does_not_have_the_torrent() { - let config = tracker_configuration(); - - let ( - _database, - _in_memory_whitelist, - whitelist_authorization, - _authentication_service, - in_memory_torrent_repository, - db_torrent_repository, - _torrents_manager, - ) = initialize_tracker_dependencies(&config); - - let tracker = initialize_tracker( - &config, - &whitelist_authorization, - &in_memory_torrent_repository, - &db_torrent_repository, - ); - - let tracker = Arc::new(tracker); + let in_memory_torrent_repository = Arc::new(InMemoryTorrentRepository::default()); let torrent_info = get_torrent_info( - tracker.clone(), + in_memory_torrent_repository.clone(), &InfoHash::from_str("0b3aea4adc213ce32295be85d3883a63bca25446").unwrap(), ) .await; @@ -202,13 +190,15 @@ mod tests { async fn should_return_the_torrent_info_if_the_tracker_has_the_torrent() { let config = tracker_configuration(); - let tracker = initialize_tracker_and_deps(&config); + let (tracker, in_memory_torrent_repository) = initialize_tracker_and_deps(&config); let hash = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); let info_hash = InfoHash::from_str(&hash).unwrap(); let _ = tracker.upsert_peer_and_get_stats(&info_hash, &sample_peer()); - let torrent_info = get_torrent_info(tracker.clone(), &info_hash).await.unwrap(); + let torrent_info = get_torrent_info(in_memory_torrent_repository.clone(), &info_hash) + .await + .unwrap(); assert_eq!( torrent_info, @@ -226,6 +216,7 @@ mod tests { mod searching_for_torrents { use std::str::FromStr; + use std::sync::Arc; use bittorrent_primitives::info_hash::InfoHash; use torrust_tracker_configuration::Configuration; @@ -233,6 +224,7 @@ mod tests { use crate::core::services::torrent::tests::{initialize_tracker_and_deps, sample_peer}; use crate::core::services::torrent::{get_torrents_page, BasicInfo, Pagination}; + use crate::core::torrent::repository::in_memory::InMemoryTorrentRepository; pub fn tracker_configuration() -> Configuration { configuration::ephemeral() @@ -240,11 +232,9 @@ mod tests { #[tokio::test] async fn should_return_an_empty_result_if_the_tracker_does_not_have_any_torrent() { - let config = tracker_configuration(); - - let tracker = initialize_tracker_and_deps(&config); + let in_memory_torrent_repository = Arc::new(InMemoryTorrentRepository::default()); - let torrents = get_torrents_page(tracker.clone(), Some(&Pagination::default())).await; + let torrents = get_torrents_page(in_memory_torrent_repository.clone(), Some(&Pagination::default())).await; assert_eq!(torrents, vec![]); } @@ -253,14 +243,14 @@ mod tests { async fn should_return_a_summarized_info_for_all_torrents() { let config = tracker_configuration(); - let tracker = initialize_tracker_and_deps(&config); + let (tracker, in_memory_torrent_repository) = initialize_tracker_and_deps(&config); let hash = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); let info_hash = InfoHash::from_str(&hash).unwrap(); let _ = tracker.upsert_peer_and_get_stats(&info_hash, &sample_peer()); - let torrents = get_torrents_page(tracker.clone(), Some(&Pagination::default())).await; + let torrents = get_torrents_page(in_memory_torrent_repository.clone(), Some(&Pagination::default())).await; assert_eq!( torrents, @@ -277,7 +267,7 @@ mod tests { async fn should_allow_limiting_the_number_of_torrents_in_the_result() { let config = tracker_configuration(); - let tracker = initialize_tracker_and_deps(&config); + let (tracker, in_memory_torrent_repository) = initialize_tracker_and_deps(&config); let hash1 = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); let info_hash1 = InfoHash::from_str(&hash1).unwrap(); @@ -290,7 +280,7 @@ mod tests { let offset = 0; let limit = 1; - let torrents = get_torrents_page(tracker.clone(), Some(&Pagination::new(offset, limit))).await; + let torrents = get_torrents_page(in_memory_torrent_repository.clone(), Some(&Pagination::new(offset, limit))).await; assert_eq!(torrents.len(), 1); } @@ -299,7 +289,7 @@ mod tests { async fn should_allow_using_pagination_in_the_result() { let config = tracker_configuration(); - let tracker = initialize_tracker_and_deps(&config); + let (tracker, in_memory_torrent_repository) = initialize_tracker_and_deps(&config); let hash1 = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); let info_hash1 = InfoHash::from_str(&hash1).unwrap(); @@ -312,7 +302,7 @@ mod tests { let offset = 1; let limit = 4000; - let torrents = get_torrents_page(tracker.clone(), Some(&Pagination::new(offset, limit))).await; + let torrents = get_torrents_page(in_memory_torrent_repository.clone(), Some(&Pagination::new(offset, limit))).await; assert_eq!(torrents.len(), 1); assert_eq!( @@ -330,7 +320,7 @@ mod tests { async fn should_return_torrents_ordered_by_info_hash() { let config = tracker_configuration(); - let tracker = initialize_tracker_and_deps(&config); + let (tracker, in_memory_torrent_repository) = initialize_tracker_and_deps(&config); let hash1 = "9e0217d0fa71c87332cd8bf9dbeabcb2c2cf3c4d".to_owned(); let info_hash1 = InfoHash::from_str(&hash1).unwrap(); @@ -340,7 +330,7 @@ mod tests { let info_hash2 = InfoHash::from_str(&hash2).unwrap(); let _ = tracker.upsert_peer_and_get_stats(&info_hash2, &sample_peer()); - let torrents = get_torrents_page(tracker.clone(), Some(&Pagination::default())).await; + let torrents = get_torrents_page(in_memory_torrent_repository.clone(), Some(&Pagination::default())).await; assert_eq!( torrents, diff --git a/src/servers/apis/routes.rs b/src/servers/apis/routes.rs index 4a005393d..c27b5f906 100644 --- a/src/servers/apis/routes.rs +++ b/src/servers/apis/routes.rs @@ -33,8 +33,8 @@ use super::v1::middlewares::auth::State; use crate::core::authentication::handler::KeysHandler; use crate::core::statistics::event::sender::Sender; use crate::core::statistics::repository::Repository; +use crate::core::torrent::repository::in_memory::InMemoryTorrentRepository; use crate::core::whitelist::manager::WhiteListManager; -use crate::core::Tracker; use crate::servers::apis::API_LOG_TARGET; use crate::servers::logging::Latency; use crate::servers::udp::server::banning::BanService; @@ -43,7 +43,6 @@ use crate::servers::udp::server::banning::BanService; #[allow(clippy::too_many_arguments)] #[allow(clippy::needless_pass_by_value)] #[instrument(skip( - tracker, keys_handler, whitelist_manager, ban_service, @@ -52,7 +51,7 @@ use crate::servers::udp::server::banning::BanService; access_tokens ))] pub fn router( - tracker: Arc, + in_memory_torrent_repository: Arc, keys_handler: Arc, whitelist_manager: Arc, ban_service: Arc>, @@ -68,7 +67,7 @@ pub fn router( let router = v1::routes::add( api_url_prefix, router, - tracker.clone(), + &in_memory_torrent_repository.clone(), &keys_handler.clone(), &whitelist_manager.clone(), ban_service.clone(), diff --git a/src/servers/apis/server.rs b/src/servers/apis/server.rs index e65d6643d..b37f71d5b 100644 --- a/src/servers/apis/server.rs +++ b/src/servers/apis/server.rs @@ -40,9 +40,10 @@ use tracing::{instrument, Level}; use super::routes::router; use crate::bootstrap::jobs::Started; use crate::core::authentication::handler::KeysHandler; +use crate::core::statistics; use crate::core::statistics::repository::Repository; +use crate::core::torrent::repository::in_memory::InMemoryTorrentRepository; use crate::core::whitelist::manager::WhiteListManager; -use crate::core::{statistics, Tracker}; use crate::servers::apis::API_LOG_TARGET; use crate::servers::custom_axum_server::{self, TimeoutAcceptor}; use crate::servers::logging::STARTED_ON; @@ -128,10 +129,10 @@ impl ApiServer { /// /// It would panic if the bound socket address cannot be sent back to this starter. #[allow(clippy::too_many_arguments)] - #[instrument(skip(self, tracker, keys_handler, whitelist_manager, stats_event_sender, ban_service, stats_repository, form, access_tokens), err, ret(Display, level = Level::INFO))] + #[instrument(skip(self, in_memory_torrent_repository, keys_handler, whitelist_manager, stats_event_sender, ban_service, stats_repository, form, access_tokens), err, ret(Display, level = Level::INFO))] pub async fn start( self, - tracker: Arc, + in_memory_torrent_repository: Arc, keys_handler: Arc, whitelist_manager: Arc, stats_event_sender: Arc>>, @@ -150,7 +151,7 @@ impl ApiServer { let _task = launcher .start( - tracker, + in_memory_torrent_repository, keys_handler, whitelist_manager, ban_service, @@ -261,7 +262,6 @@ impl Launcher { #[allow(clippy::too_many_arguments)] #[instrument(skip( self, - tracker, keys_handler, whitelist_manager, ban_service, @@ -273,7 +273,7 @@ impl Launcher { ))] pub fn start( &self, - tracker: Arc, + in_memory_torrent_repository: Arc, keys_handler: Arc, whitelist_manager: Arc, ban_service: Arc>, @@ -287,7 +287,7 @@ impl Launcher { let address = socket.local_addr().expect("Could not get local_addr from tcp_listener."); let router = router( - tracker, + in_memory_torrent_repository, keys_handler, whitelist_manager, ban_service, @@ -373,7 +373,7 @@ mod tests { let started = stopped .start( - app_container.tracker, + app_container.in_memory_torrent_repository, app_container.keys_handler, app_container.whitelist_manager, app_container.stats_event_sender, diff --git a/src/servers/apis/v1/context/stats/handlers.rs b/src/servers/apis/v1/context/stats/handlers.rs index af7e1c239..da87696fc 100644 --- a/src/servers/apis/v1/context/stats/handlers.rs +++ b/src/servers/apis/v1/context/stats/handlers.rs @@ -11,7 +11,7 @@ use tokio::sync::RwLock; use super::responses::{metrics_response, stats_response}; use crate::core::services::statistics::get_metrics; use crate::core::statistics::repository::Repository; -use crate::core::Tracker; +use crate::core::torrent::repository::in_memory::InMemoryTorrentRepository; use crate::servers::udp::server::banning::BanService; #[derive(Deserialize, Debug, Default)] @@ -40,7 +40,7 @@ pub struct QueryParams { /// for more information about this endpoint. #[allow(clippy::type_complexity)] pub async fn get_stats_handler( - State(state): State<(Arc, Arc>, Arc)>, + State(state): State<(Arc, Arc>, Arc)>, params: Query, ) -> Response { let metrics = get_metrics(state.0.clone(), state.1.clone(), state.2.clone()).await; diff --git a/src/servers/apis/v1/context/stats/routes.rs b/src/servers/apis/v1/context/stats/routes.rs index b5df32963..083c72b10 100644 --- a/src/servers/apis/v1/context/stats/routes.rs +++ b/src/servers/apis/v1/context/stats/routes.rs @@ -12,20 +12,20 @@ use tokio::sync::RwLock; use super::handlers::get_stats_handler; use crate::core::statistics::event::sender::Sender; use crate::core::statistics::repository::Repository; -use crate::core::Tracker; +use crate::core::torrent::repository::in_memory::InMemoryTorrentRepository; use crate::servers::udp::server::banning::BanService; /// It adds the routes to the router for the [`stats`](crate::servers::apis::v1::context::stats) API context. pub fn add( prefix: &str, router: Router, - tracker: Arc, + in_memory_torrent_repository: Arc, ban_service: Arc>, _stats_event_sender: Arc>>, stats_repository: Arc, ) -> Router { router.route( &format!("{prefix}/stats"), - get(get_stats_handler).with_state((tracker, ban_service, stats_repository)), + get(get_stats_handler).with_state((in_memory_torrent_repository, ban_service, stats_repository)), ) } diff --git a/src/servers/apis/v1/context/torrent/handlers.rs b/src/servers/apis/v1/context/torrent/handlers.rs index 0ba713f62..8fe20ab80 100644 --- a/src/servers/apis/v1/context/torrent/handlers.rs +++ b/src/servers/apis/v1/context/torrent/handlers.rs @@ -14,7 +14,7 @@ use torrust_tracker_primitives::pagination::Pagination; use super::responses::{torrent_info_response, torrent_list_response, torrent_not_known_response}; use crate::core::services::torrent::{get_torrent_info, get_torrents, get_torrents_page}; -use crate::core::Tracker; +use crate::core::torrent::repository::in_memory::InMemoryTorrentRepository; use crate::servers::apis::v1::responses::invalid_info_hash_param_response; use crate::servers::apis::InfoHashParam; @@ -27,10 +27,13 @@ use crate::servers::apis::InfoHashParam; /// /// Refer to the [API endpoint documentation](crate::servers::apis::v1::context::torrent#get-a-torrent) /// for more information about this endpoint. -pub async fn get_torrent_handler(State(tracker): State>, Path(info_hash): Path) -> Response { +pub async fn get_torrent_handler( + State(in_memory_torrent_repository): State>, + Path(info_hash): Path, +) -> Response { match InfoHash::from_str(&info_hash.0) { Err(_) => invalid_info_hash_param_response(&info_hash.0), - Ok(info_hash) => match get_torrent_info(tracker.clone(), &info_hash).await { + Ok(info_hash) => match get_torrent_info(in_memory_torrent_repository.clone(), &info_hash).await { Some(info) => torrent_info_response(info).into_response(), None => torrent_not_known_response(), }, @@ -75,13 +78,16 @@ pub struct QueryParams { /// /// Refer to the [API endpoint documentation](crate::servers::apis::v1::context::torrent#list-torrents) /// for more information about this endpoint. -pub async fn get_torrents_handler(State(tracker): State>, pagination: Query) -> Response { +pub async fn get_torrents_handler( + State(in_memory_torrent_repository): State>, + pagination: Query, +) -> Response { tracing::debug!("pagination: {:?}", pagination); if pagination.0.info_hashes.is_empty() { torrent_list_response( &get_torrents_page( - tracker.clone(), + in_memory_torrent_repository.clone(), Some(&Pagination::new_with_options(pagination.0.offset, pagination.0.limit)), ) .await, @@ -89,7 +95,9 @@ pub async fn get_torrents_handler(State(tracker): State>, paginatio .into_response() } else { match parse_info_hashes(pagination.0.info_hashes) { - Ok(info_hashes) => torrent_list_response(&get_torrents(tracker.clone(), &info_hashes).await).into_response(), + Ok(info_hashes) => { + torrent_list_response(&get_torrents(in_memory_torrent_repository.clone(), &info_hashes).await).into_response() + } Err(err) => match err { QueryParamError::InvalidInfoHash { info_hash } => invalid_info_hash_param_response(&info_hash), }, diff --git a/src/servers/apis/v1/context/torrent/routes.rs b/src/servers/apis/v1/context/torrent/routes.rs index bca594e3d..dc66a1753 100644 --- a/src/servers/apis/v1/context/torrent/routes.rs +++ b/src/servers/apis/v1/context/torrent/routes.rs @@ -10,15 +10,18 @@ use axum::routing::get; use axum::Router; use super::handlers::{get_torrent_handler, get_torrents_handler}; -use crate::core::Tracker; +use crate::core::torrent::repository::in_memory::InMemoryTorrentRepository; /// It adds the routes to the router for the [`torrent`](crate::servers::apis::v1::context::torrent) API context. -pub fn add(prefix: &str, router: Router, tracker: Arc) -> Router { +pub fn add(prefix: &str, router: Router, in_memory_torrent_repository: Arc) -> Router { // Torrents router .route( &format!("{prefix}/torrent/{{info_hash}}"), - get(get_torrent_handler).with_state(tracker.clone()), + get(get_torrent_handler).with_state(in_memory_torrent_repository.clone()), + ) + .route( + &format!("{prefix}/torrents"), + get(get_torrents_handler).with_state(in_memory_torrent_repository), ) - .route(&format!("{prefix}/torrents"), get(get_torrents_handler).with_state(tracker)) } diff --git a/src/servers/apis/v1/routes.rs b/src/servers/apis/v1/routes.rs index c26ce4f3d..8fac453b8 100644 --- a/src/servers/apis/v1/routes.rs +++ b/src/servers/apis/v1/routes.rs @@ -8,8 +8,8 @@ use super::context::{auth_key, stats, torrent, whitelist}; use crate::core::authentication::handler::KeysHandler; use crate::core::statistics::event::sender::Sender; use crate::core::statistics::repository::Repository; +use crate::core::torrent::repository::in_memory::InMemoryTorrentRepository; use crate::core::whitelist::manager::WhiteListManager; -use crate::core::Tracker; use crate::servers::udp::server::banning::BanService; /// Add the routes for the v1 API. @@ -17,7 +17,7 @@ use crate::servers::udp::server::banning::BanService; pub fn add( prefix: &str, router: Router, - tracker: Arc, + in_memory_torrent_repository: &Arc, keys_handler: &Arc, whitelist_manager: &Arc, ban_service: Arc>, @@ -30,12 +30,12 @@ pub fn add( let router = stats::routes::add( &v1_prefix, router, - tracker.clone(), + in_memory_torrent_repository.clone(), ban_service, stats_event_sender, stats_repository, ); let router = whitelist::routes::add(&v1_prefix, router, whitelist_manager); - torrent::routes::add(&v1_prefix, router, tracker) + torrent::routes::add(&v1_prefix, router, in_memory_torrent_repository.clone()) } diff --git a/src/servers/udp/handlers.rs b/src/servers/udp/handlers.rs index fd2a37683..c88f6fdc9 100644 --- a/src/servers/udp/handlers.rs +++ b/src/servers/udp/handlers.rs @@ -486,6 +486,7 @@ mod tests { use crate::app_test::initialize_tracker_dependencies; use crate::core::services::{initialize_tracker, initialize_whitelist_manager, statistics}; use crate::core::statistics::event::sender::Sender; + use crate::core::torrent::repository::in_memory::InMemoryTorrentRepository; use crate::core::whitelist::manager::WhiteListManager; use crate::core::whitelist::repository::in_memory::InMemoryWhitelist; use crate::core::{whitelist, Tracker}; @@ -493,6 +494,7 @@ mod tests { type TrackerAndDeps = ( Arc, + Arc, Arc>>, Arc, Arc, @@ -539,6 +541,7 @@ mod tests { ( tracker, + in_memory_torrent_repository, stats_event_sender, in_memory_whitelist, whitelist_manager, @@ -887,8 +890,14 @@ mod tests { #[tokio::test] async fn an_announced_peer_should_be_added_to_the_tracker() { - let (tracker, stats_event_sender, _in_memory_whitelist, _whitelist_manager, whitelist_authorization) = - public_tracker(); + let ( + tracker, + in_memory_torrent_repository, + stats_event_sender, + _in_memory_whitelist, + _whitelist_manager, + whitelist_authorization, + ) = public_tracker(); let client_ip = Ipv4Addr::new(126, 0, 0, 1); let client_port = 8080; @@ -916,7 +925,7 @@ mod tests { .await .unwrap(); - let peers = tracker.in_memory_torrent_repository.get_torrent_peers(&info_hash.0.into()); + let peers = in_memory_torrent_repository.get_torrent_peers(&info_hash.0.into()); let expected_peer = TorrentPeerBuilder::new() .with_peer_id(peer_id) @@ -928,8 +937,14 @@ mod tests { #[tokio::test] async fn the_announced_peer_should_not_be_included_in_the_response() { - let (tracker, stats_event_sender, _in_memory_whitelist, _whitelist_manager, whitelist_authorization) = - public_tracker(); + let ( + tracker, + _in_memory_torrent_repository, + stats_event_sender, + _in_memory_whitelist, + _whitelist_manager, + whitelist_authorization, + ) = public_tracker(); let remote_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(126, 0, 0, 1)), 8080); @@ -969,8 +984,14 @@ mod tests { // From the BEP 15 (https://www.bittorrent.org/beps/bep_0015.html): // "Do note that most trackers will only honor the IP address field under limited circumstances." - let (tracker, stats_event_sender, _in_memory_whitelist, _whitelist_manager, whitelist_authorization) = - public_tracker(); + let ( + tracker, + in_memory_torrent_repository, + stats_event_sender, + _in_memory_whitelist, + _whitelist_manager, + whitelist_authorization, + ) = public_tracker(); let info_hash = AquaticInfoHash([0u8; 20]); let peer_id = AquaticPeerId([255u8; 20]); @@ -1001,7 +1022,7 @@ mod tests { .await .unwrap(); - let peers = tracker.in_memory_torrent_repository.get_torrent_peers(&info_hash.0.into()); + let peers = in_memory_torrent_repository.get_torrent_peers(&info_hash.0.into()); assert_eq!(peers[0].peer_addr, SocketAddr::new(IpAddr::V4(remote_client_ip), client_port)); } @@ -1048,8 +1069,14 @@ mod tests { #[tokio::test] async fn when_the_announce_request_comes_from_a_client_using_ipv4_the_response_should_not_include_peers_using_ipv6() { - let (tracker, _stats_event_sender, _in_memory_whitelist, _whitelist_manager, whitelist_authorization) = - public_tracker(); + let ( + tracker, + _in_memory_torrent_repository, + _stats_event_sender, + _in_memory_whitelist, + _whitelist_manager, + whitelist_authorization, + ) = public_tracker(); add_a_torrent_peer_using_ipv6(&tracker); @@ -1104,8 +1131,14 @@ mod tests { #[tokio::test] async fn the_peer_ip_should_be_changed_to_the_external_ip_in_the_tracker_configuration_if_defined() { - let (tracker, stats_event_sender, _in_memory_whitelist, _whitelist_manager, whitelist_authorization) = - public_tracker(); + let ( + tracker, + in_memory_torrent_repository, + stats_event_sender, + _in_memory_whitelist, + _whitelist_manager, + whitelist_authorization, + ) = public_tracker(); let client_ip = Ipv4Addr::new(127, 0, 0, 1); let client_port = 8080; @@ -1133,7 +1166,7 @@ mod tests { .await .unwrap(); - let peers = tracker.in_memory_torrent_repository.get_torrent_peers(&info_hash.0.into()); + let peers = in_memory_torrent_repository.get_torrent_peers(&info_hash.0.into()); let external_ip_in_tracker_configuration = tracker.get_maybe_external_ip().unwrap(); @@ -1170,8 +1203,14 @@ mod tests { #[tokio::test] async fn an_announced_peer_should_be_added_to_the_tracker() { - let (tracker, stats_event_sender, _in_memory_whitelist, _whitelist_manager, whitelist_authorization) = - public_tracker(); + let ( + tracker, + in_memory_torrent_repository, + stats_event_sender, + _in_memory_whitelist, + _whitelist_manager, + whitelist_authorization, + ) = public_tracker(); let client_ip_v4 = Ipv4Addr::new(126, 0, 0, 1); let client_ip_v6 = client_ip_v4.to_ipv6_compatible(); @@ -1200,7 +1239,7 @@ mod tests { .await .unwrap(); - let peers = tracker.in_memory_torrent_repository.get_torrent_peers(&info_hash.0.into()); + let peers = in_memory_torrent_repository.get_torrent_peers(&info_hash.0.into()); let expected_peer = TorrentPeerBuilder::new() .with_peer_id(peer_id) @@ -1212,8 +1251,14 @@ mod tests { #[tokio::test] async fn the_announced_peer_should_not_be_included_in_the_response() { - let (tracker, stats_event_sender, _in_memory_whitelist, _whitelist_manager, whitelist_authorization) = - public_tracker(); + let ( + tracker, + _in_memory_torrent_repository, + stats_event_sender, + _in_memory_whitelist, + _whitelist_manager, + whitelist_authorization, + ) = public_tracker(); let client_ip_v4 = Ipv4Addr::new(126, 0, 0, 1); let client_ip_v6 = client_ip_v4.to_ipv6_compatible(); @@ -1256,8 +1301,14 @@ mod tests { // From the BEP 15 (https://www.bittorrent.org/beps/bep_0015.html): // "Do note that most trackers will only honor the IP address field under limited circumstances." - let (tracker, stats_event_sender, _in_memory_whitelist, _whitelist_manager, whitelist_authorization) = - public_tracker(); + let ( + tracker, + in_memory_torrent_repository, + stats_event_sender, + _in_memory_whitelist, + _whitelist_manager, + whitelist_authorization, + ) = public_tracker(); let info_hash = AquaticInfoHash([0u8; 20]); let peer_id = AquaticPeerId([255u8; 20]); @@ -1288,7 +1339,7 @@ mod tests { .await .unwrap(); - let peers = tracker.in_memory_torrent_repository.get_torrent_peers(&info_hash.0.into()); + let peers = in_memory_torrent_repository.get_torrent_peers(&info_hash.0.into()); // When using IPv6 the tracker converts the remote client ip into a IPv4 address assert_eq!(peers[0].peer_addr, SocketAddr::new(IpAddr::V6(remote_client_ip), client_port)); @@ -1338,8 +1389,14 @@ mod tests { #[tokio::test] async fn when_the_announce_request_comes_from_a_client_using_ipv6_the_response_should_not_include_peers_using_ipv4() { - let (tracker, _stats_event_sender, _in_memory_whitelist, _whitelist_manager, whitelist_authorization) = - public_tracker(); + let ( + tracker, + _in_memory_torrent_repository, + _stats_event_sender, + _in_memory_whitelist, + _whitelist_manager, + whitelist_authorization, + ) = public_tracker(); add_a_torrent_peer_using_ipv4(&tracker); @@ -1466,7 +1523,7 @@ mod tests { .await .unwrap(); - let peers = tracker.in_memory_torrent_repository.get_torrent_peers(&info_hash.0.into()); + let peers = in_memory_torrent_repository.get_torrent_peers(&info_hash.0.into()); let external_ip_in_tracker_configuration = tracker.get_maybe_external_ip().unwrap(); @@ -1511,8 +1568,14 @@ mod tests { #[tokio::test] async fn should_return_no_stats_when_the_tracker_does_not_have_any_torrent() { - let (tracker, stats_event_sender, _in_memory_whitelist, _whitelist_manager, _whitelist_authorization) = - public_tracker(); + let ( + tracker, + _in_memory_torrent_repository, + stats_event_sender, + _in_memory_whitelist, + _whitelist_manager, + _whitelist_authorization, + ) = public_tracker(); let remote_addr = sample_ipv4_remote_addr(); @@ -1605,8 +1668,14 @@ mod tests { #[tokio::test] async fn should_return_torrent_statistics_when_the_tracker_has_the_requested_torrent() { - let (tracker, _stats_event_sender, _in_memory_whitelist, _whitelist_manager, _whitelist_authorization) = - public_tracker(); + let ( + tracker, + _in_memory_torrent_repository, + _stats_event_sender, + _in_memory_whitelist, + _whitelist_manager, + _whitelist_authorization, + ) = public_tracker(); let torrent_stats = match_scrape_response(add_a_sample_seeder_and_scrape(tracker.clone()).await); @@ -1631,8 +1700,14 @@ mod tests { #[tokio::test] async fn should_return_the_torrent_statistics_when_the_requested_torrent_is_whitelisted() { - let (tracker, stats_event_sender, in_memory_whitelist, _whitelist_manager, _whitelist_authorization) = - whitelisted_tracker(); + let ( + tracker, + _in_memory_torrent_repository, + stats_event_sender, + in_memory_whitelist, + _whitelist_manager, + _whitelist_authorization, + ) = whitelisted_tracker(); let remote_addr = sample_ipv4_remote_addr(); let info_hash = InfoHash([0u8; 20]); @@ -1667,8 +1742,14 @@ mod tests { #[tokio::test] async fn should_return_zeroed_statistics_when_the_requested_torrent_is_not_whitelisted() { - let (tracker, stats_event_sender, _in_memory_whitelist, _whitelist_manager, _whitelist_authorization) = - whitelisted_tracker(); + let ( + tracker, + _in_memory_torrent_repository, + stats_event_sender, + _in_memory_whitelist, + _whitelist_manager, + _whitelist_authorization, + ) = whitelisted_tracker(); let remote_addr = sample_ipv4_remote_addr(); let info_hash = InfoHash([0u8; 20]); diff --git a/tests/servers/api/environment.rs b/tests/servers/api/environment.rs index 8967ff830..70f071bf4 100644 --- a/tests/servers/api/environment.rs +++ b/tests/servers/api/environment.rs @@ -13,6 +13,7 @@ use torrust_tracker_lib::core::authentication::service::AuthenticationService; use torrust_tracker_lib::core::databases::Database; use torrust_tracker_lib::core::statistics::event::sender::Sender; use torrust_tracker_lib::core::statistics::repository::Repository; +use torrust_tracker_lib::core::torrent::repository::in_memory::InMemoryTorrentRepository; use torrust_tracker_lib::core::whitelist::manager::WhiteListManager; use torrust_tracker_lib::core::Tracker; use torrust_tracker_lib::servers::apis::server::{ApiServer, Launcher, Running, Stopped}; @@ -27,6 +28,7 @@ where pub config: Arc, pub database: Arc>, pub tracker: Arc, + pub in_memory_torrent_repository: Arc, pub keys_handler: Arc, pub authentication_service: Arc, pub stats_event_sender: Arc>>, @@ -65,6 +67,7 @@ impl Environment { config, database: app_container.database.clone(), tracker: app_container.tracker.clone(), + in_memory_torrent_repository: app_container.in_memory_torrent_repository.clone(), keys_handler: app_container.keys_handler.clone(), authentication_service: app_container.authentication_service.clone(), stats_event_sender: app_container.stats_event_sender.clone(), @@ -83,6 +86,7 @@ impl Environment { config: self.config, database: self.database.clone(), tracker: self.tracker.clone(), + in_memory_torrent_repository: self.in_memory_torrent_repository.clone(), keys_handler: self.keys_handler.clone(), authentication_service: self.authentication_service.clone(), stats_event_sender: self.stats_event_sender.clone(), @@ -93,7 +97,7 @@ impl Environment { server: self .server .start( - self.tracker, + self.in_memory_torrent_repository, self.keys_handler, self.whitelist_manager, self.stats_event_sender, @@ -118,6 +122,7 @@ impl Environment { config: self.config, database: self.database, tracker: self.tracker, + in_memory_torrent_repository: self.in_memory_torrent_repository, keys_handler: self.keys_handler, authentication_service: self.authentication_service, stats_event_sender: self.stats_event_sender, diff --git a/tests/servers/http/environment.rs b/tests/servers/http/environment.rs index 80c042a21..c0de4efbe 100644 --- a/tests/servers/http/environment.rs +++ b/tests/servers/http/environment.rs @@ -10,6 +10,7 @@ use torrust_tracker_lib::core::authentication::service::AuthenticationService; use torrust_tracker_lib::core::databases::Database; use torrust_tracker_lib::core::statistics::event::sender::Sender; use torrust_tracker_lib::core::statistics::repository::Repository; +use torrust_tracker_lib::core::torrent::repository::in_memory::InMemoryTorrentRepository; use torrust_tracker_lib::core::whitelist::manager::WhiteListManager; use torrust_tracker_lib::core::{whitelist, Tracker}; use torrust_tracker_lib::servers::http::server::{HttpServer, Launcher, Running, Stopped}; @@ -20,6 +21,7 @@ pub struct Environment { pub config: Arc, pub database: Arc>, pub tracker: Arc, + pub in_memory_torrent_repository: Arc, pub keys_handler: Arc, pub authentication_service: Arc, pub stats_event_sender: Arc>>, @@ -61,6 +63,7 @@ impl Environment { config, database: app_container.database.clone(), tracker: app_container.tracker.clone(), + in_memory_torrent_repository: app_container.in_memory_torrent_repository.clone(), keys_handler: app_container.keys_handler.clone(), authentication_service: app_container.authentication_service.clone(), stats_event_sender: app_container.stats_event_sender.clone(), @@ -78,6 +81,7 @@ impl Environment { config: self.config, database: self.database.clone(), tracker: self.tracker.clone(), + in_memory_torrent_repository: self.in_memory_torrent_repository.clone(), keys_handler: self.keys_handler.clone(), authentication_service: self.authentication_service.clone(), whitelist_authorization: self.whitelist_authorization.clone(), @@ -110,6 +114,7 @@ impl Environment { config: self.config, database: self.database, tracker: self.tracker, + in_memory_torrent_repository: self.in_memory_torrent_repository, keys_handler: self.keys_handler, authentication_service: self.authentication_service, whitelist_authorization: self.whitelist_authorization, diff --git a/tests/servers/http/v1/contract.rs b/tests/servers/http/v1/contract.rs index 31aae9b50..8a65d941a 100644 --- a/tests/servers/http/v1/contract.rs +++ b/tests/servers/http/v1/contract.rs @@ -831,7 +831,7 @@ mod for_all_config_modes { assert_eq!(status, StatusCode::OK); } - let peers = env.tracker.in_memory_torrent_repository.get_torrent_peers(&info_hash); + let peers = env.in_memory_torrent_repository.get_torrent_peers(&info_hash); let peer_addr = peers[0].peer_addr; assert_eq!(peer_addr.ip(), client_ip); @@ -869,7 +869,7 @@ mod for_all_config_modes { assert_eq!(status, StatusCode::OK); } - let peers = env.tracker.in_memory_torrent_repository.get_torrent_peers(&info_hash); + let peers = env.in_memory_torrent_repository.get_torrent_peers(&info_hash); let peer_addr = peers[0].peer_addr; assert_eq!(peer_addr.ip(), env.tracker.get_maybe_external_ip().unwrap()); @@ -911,7 +911,7 @@ mod for_all_config_modes { assert_eq!(status, StatusCode::OK); } - let peers = env.tracker.in_memory_torrent_repository.get_torrent_peers(&info_hash); + let peers = env.in_memory_torrent_repository.get_torrent_peers(&info_hash); let peer_addr = peers[0].peer_addr; assert_eq!(peer_addr.ip(), env.tracker.get_maybe_external_ip().unwrap()); @@ -951,7 +951,7 @@ mod for_all_config_modes { assert_eq!(status, StatusCode::OK); } - let peers = env.tracker.in_memory_torrent_repository.get_torrent_peers(&info_hash); + let peers = env.in_memory_torrent_repository.get_torrent_peers(&info_hash); let peer_addr = peers[0].peer_addr; assert_eq!(peer_addr.ip(), IpAddr::from_str("150.172.238.178").unwrap());