Skip to content

Commit

Permalink
refactor: [torrust#1182] inject database and whitelist in tracker as dep
Browse files Browse the repository at this point in the history
Inject the database (persistence) and whitelist manager into the Tracker
via the contructor to be able to use the whitelist manager directly in
Axum handlers.
  • Loading branch information
josecelano committed Jan 15, 2025
1 parent cc2bc7b commit 2f1abeb
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 142 deletions.
17 changes: 5 additions & 12 deletions src/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -457,11 +457,9 @@ use std::time::Duration;

use auth::PeerKey;
use bittorrent_primitives::info_hash::InfoHash;
use databases::driver::Driver;
use error::PeerKeyError;
use tokio::sync::mpsc::error::SendError;
use torrust_tracker_clock::clock::Time;
use torrust_tracker_configuration::v2_0_0::database;
use torrust_tracker_configuration::{AnnouncePolicy, Core, TORRENT_PEERS_LIMIT};
use torrust_tracker_located_error::Located;
use torrust_tracker_primitives::core::{AnnounceData, ScrapeData};
Expand Down Expand Up @@ -500,7 +498,7 @@ pub struct Tracker {
keys: tokio::sync::RwLock<std::collections::HashMap<Key, auth::PeerKey>>,

/// The list of allowed torrents. Only for listed trackers.
pub whitelist_manager: WhiteListManager,
pub whitelist_manager: Arc<WhiteListManager>,

/// The in-memory torrents repository.
torrents: Arc<Torrents>,
Expand Down Expand Up @@ -576,24 +574,19 @@ impl Tracker {
/// Will return a `databases::error::Error` if unable to connect to database. The `Tracker` is responsible for the persistence.
pub fn new(
config: &Core,
database: &Arc<Box<dyn Database>>,
whitelist_manager: &Arc<WhiteListManager>,
stats_event_sender: Option<Box<dyn statistics::event::sender::Sender>>,
stats_repository: statistics::repository::Repository,
) -> Result<Tracker, databases::error::Error> {
let driver = match config.database.driver {
database::Driver::Sqlite3 => Driver::Sqlite3,
database::Driver::MySQL => Driver::MySQL,
};

let database = Arc::new(databases::driver::build(&driver, &config.database.path)?);

Ok(Tracker {
config: config.clone(),
database: database.clone(),
keys: tokio::sync::RwLock::new(std::collections::HashMap::new()),
whitelist_manager: WhiteListManager::new(database.clone()),
whitelist_manager: whitelist_manager.clone(),
torrents: Arc::default(),
stats_event_sender,
stats_repository,
database,
})
}

Expand Down
38 changes: 35 additions & 3 deletions src/core/services/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@ pub mod torrent;

use std::sync::Arc;

use databases::driver::Driver;
use torrust_tracker_configuration::v2_0_0::database;
use torrust_tracker_configuration::Configuration;

use super::databases::{self, Database};
use super::whitelist::persisted::DatabaseWhitelist;
use super::whitelist::WhiteListManager;
use crate::core::Tracker;

/// It returns a new tracker building its dependencies.
Expand All @@ -20,14 +25,41 @@ use crate::core::Tracker;
/// Will panic if tracker cannot be instantiated.
#[must_use]
pub fn tracker_factory(config: &Configuration) -> Tracker {
// Initialize statistics
let database = initialize_database(config);

let whitelist_manager = initialize_whitelist(database.clone());

let (stats_event_sender, stats_repository) = statistics::setup::factory(config.core.tracker_usage_statistics);

// Initialize Torrust tracker
match Tracker::new(&Arc::new(config).core, stats_event_sender, stats_repository) {
match Tracker::new(
&Arc::new(config).core,
&database,
&whitelist_manager,
stats_event_sender,
stats_repository,
) {
Ok(tracker) => tracker,
Err(error) => {
panic!("{}", error)
}
}
}

/// # Panics
///
/// Will panic if database cannot be initialized.
#[must_use]
pub fn initialize_database(config: &Configuration) -> Arc<Box<dyn Database>> {
let driver = match config.core.database.driver {
database::Driver::Sqlite3 => Driver::Sqlite3,
database::Driver::MySQL => Driver::MySQL,
};

Arc::new(databases::driver::build(&driver, &config.core.database.path).expect("Database driver build failed."))
}

#[must_use]
pub fn initialize_whitelist(database: Arc<Box<dyn Database>>) -> Arc<WhiteListManager> {
let database_whitelist = Arc::new(DatabaseWhitelist::new(database));
Arc::new(WhiteListManager::new(database_whitelist))
}
8 changes: 4 additions & 4 deletions src/core/whitelist/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,23 @@ use bittorrent_primitives::info_hash::InfoHash;
use in_memory::InMemoryWhitelist;
use persisted::DatabaseWhitelist;

use super::databases::{self, Database};
use super::databases::{self};

/// It handles the list of allowed torrents. Only for listed trackers.
pub struct WhiteListManager {
/// The in-memory list of allowed torrents.
in_memory_whitelist: InMemoryWhitelist,

/// The persisted list of allowed torrents.
database_whitelist: DatabaseWhitelist,
database_whitelist: Arc<DatabaseWhitelist>,
}

impl WhiteListManager {
#[must_use]
pub fn new(database: Arc<Box<dyn Database>>) -> Self {
pub fn new(database_whitelist: Arc<DatabaseWhitelist>) -> Self {
Self {
in_memory_whitelist: InMemoryWhitelist::default(),
database_whitelist: DatabaseWhitelist::new(database),
database_whitelist,
}
}

Expand Down
43 changes: 21 additions & 22 deletions src/servers/http/v1/services/announce.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,28 @@ mod tests {
use torrust_tracker_test_helpers::configuration;

use super::{sample_peer_using_ipv4, sample_peer_using_ipv6};
use crate::core::services::{initialize_database, initialize_whitelist};
use crate::core::{statistics, PeersWanted, Tracker};
use crate::servers::http::v1::services::announce::invoke;
use crate::servers::http::v1::services::announce::tests::{public_tracker, sample_info_hash, sample_peer};

fn test_tracker_factory(stats_event_sender: Option<Box<dyn statistics::event::sender::Sender>>) -> Tracker {
let config = configuration::ephemeral();

let database = initialize_database(&config);

let whitelist_manager = initialize_whitelist(database.clone());

Tracker::new(
&config.core,
&database,
&whitelist_manager,
stats_event_sender,
statistics::repository::Repository::new(),
)
.unwrap()
}

#[tokio::test]
async fn it_should_return_the_announce_data() {
let tracker = Arc::new(public_tracker());
Expand Down Expand Up @@ -142,14 +160,7 @@ mod tests {
.returning(|_| Box::pin(future::ready(Some(Ok(())))));
let stats_event_sender = Box::new(stats_event_sender_mock);

let tracker = Arc::new(
Tracker::new(
&configuration::ephemeral().core,
Some(stats_event_sender),
statistics::repository::Repository::new(),
)
.unwrap(),
);
let tracker = Arc::new(test_tracker_factory(Some(stats_event_sender)));

let mut peer = sample_peer_using_ipv4();

Expand All @@ -162,12 +173,7 @@ mod tests {
0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969,
)));

Tracker::new(
&configuration.core,
Some(stats_event_sender),
statistics::repository::Repository::new(),
)
.unwrap()
test_tracker_factory(Some(stats_event_sender))
}

fn peer_with_the_ipv4_loopback_ip() -> peer::Peer {
Expand Down Expand Up @@ -213,14 +219,7 @@ mod tests {
.returning(|_| Box::pin(future::ready(Some(Ok(())))));
let stats_event_sender = Box::new(stats_event_sender_mock);

let tracker = Arc::new(
Tracker::new(
&configuration::ephemeral().core,
Some(stats_event_sender),
statistics::repository::Repository::new(),
)
.unwrap(),
);
let tracker = Arc::new(test_tracker_factory(Some(stats_event_sender)));

let mut peer = sample_peer_using_ipv6();

Expand Down
67 changes: 27 additions & 40 deletions src/servers/http/v1/services/scrape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ mod tests {
use torrust_tracker_primitives::{peer, DurationSinceUnixEpoch};
use torrust_tracker_test_helpers::configuration;

use crate::core::services::tracker_factory;
use crate::core::Tracker;
use crate::core::services::{initialize_database, initialize_whitelist, tracker_factory};
use crate::core::{statistics, Tracker};

fn public_tracker() -> Tracker {
tracker_factory(&configuration::ephemeral_public())
Expand All @@ -94,6 +94,23 @@ mod tests {
}
}

fn test_tracker_factory(stats_event_sender: Option<Box<dyn statistics::event::sender::Sender>>) -> Tracker {
let config = configuration::ephemeral();

let database = initialize_database(&config);

let whitelist_manager = initialize_whitelist(database.clone());

Tracker::new(
&config.core,
&database,
&whitelist_manager,
stats_event_sender,
statistics::repository::Repository::new(),
)
.unwrap()
}

mod with_real_data {

use std::future;
Expand All @@ -103,12 +120,11 @@ mod tests {
use mockall::predicate::eq;
use torrust_tracker_primitives::core::ScrapeData;
use torrust_tracker_primitives::swarm_metadata::SwarmMetadata;
use torrust_tracker_test_helpers::configuration;

use crate::core::{statistics, PeersWanted, Tracker};
use crate::core::{statistics, PeersWanted};
use crate::servers::http::v1::services::scrape::invoke;
use crate::servers::http::v1::services::scrape::tests::{
public_tracker, sample_info_hash, sample_info_hashes, sample_peer,
public_tracker, sample_info_hash, sample_info_hashes, sample_peer, test_tracker_factory,
};

#[tokio::test]
Expand Down Expand Up @@ -148,14 +164,7 @@ mod tests {
.returning(|_| Box::pin(future::ready(Some(Ok(())))));
let stats_event_sender = Box::new(stats_event_sender_mock);

let tracker = Arc::new(
Tracker::new(
&configuration::ephemeral().core,
Some(stats_event_sender),
statistics::repository::Repository::new(),
)
.unwrap(),
);
let tracker = Arc::new(test_tracker_factory(Some(stats_event_sender)));

let peer_ip = IpAddr::V4(Ipv4Addr::new(126, 0, 0, 1));

Expand All @@ -172,14 +181,7 @@ mod tests {
.returning(|_| Box::pin(future::ready(Some(Ok(())))));
let stats_event_sender = Box::new(stats_event_sender_mock);

let tracker = Arc::new(
Tracker::new(
&configuration::ephemeral().core,
Some(stats_event_sender),
statistics::repository::Repository::new(),
)
.unwrap(),
);
let tracker = Arc::new(test_tracker_factory(Some(stats_event_sender)));

let peer_ip = IpAddr::V6(Ipv6Addr::new(0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969));

Expand All @@ -195,12 +197,11 @@ mod tests {

use mockall::predicate::eq;
use torrust_tracker_primitives::core::ScrapeData;
use torrust_tracker_test_helpers::configuration;

use crate::core::{statistics, PeersWanted, Tracker};
use crate::core::{statistics, PeersWanted};
use crate::servers::http::v1::services::scrape::fake;
use crate::servers::http::v1::services::scrape::tests::{
public_tracker, sample_info_hash, sample_info_hashes, sample_peer,
public_tracker, sample_info_hash, sample_info_hashes, sample_peer, test_tracker_factory,
};

#[tokio::test]
Expand Down Expand Up @@ -232,14 +233,7 @@ mod tests {
.returning(|_| Box::pin(future::ready(Some(Ok(())))));
let stats_event_sender = Box::new(stats_event_sender_mock);

let tracker = Arc::new(
Tracker::new(
&configuration::ephemeral().core,
Some(stats_event_sender),
statistics::repository::Repository::new(),
)
.unwrap(),
);
let tracker = Arc::new(test_tracker_factory(Some(stats_event_sender)));

let peer_ip = IpAddr::V4(Ipv4Addr::new(126, 0, 0, 1));

Expand All @@ -256,14 +250,7 @@ mod tests {
.returning(|_| Box::pin(future::ready(Some(Ok(())))));
let stats_event_sender = Box::new(stats_event_sender_mock);

let tracker = Arc::new(
Tracker::new(
&configuration::ephemeral().core,
Some(stats_event_sender),
statistics::repository::Repository::new(),
)
.unwrap(),
);
let tracker = Arc::new(test_tracker_factory(Some(stats_event_sender)));

let peer_ip = IpAddr::V6(Ipv6Addr::new(0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969, 0x6969));

Expand Down
Loading

0 comments on commit 2f1abeb

Please sign in to comment.