Skip to content

SI-30: Decouple rest-api-core and axum-rest-api-server from concrete UDP server internals #1924

Description

@josecelano

Subissue of EPIC #1669 — Overhaul: Packages

Note: this is a production code decoupling (unlike the server environment.rs relocations which only move test infrastructure). It changes rest-api-core containers/services and axum-rest-api-server handlers/routes to use trait abstractions instead of concrete UDP types.

Implemented after the environment.rs relocations (subissues SI-23/SI-24/SI-25) — those were test infrastructure moves, while this is a production dependency decoupling.

Problem

Two packages import concrete UDP types, forcing runtime dependencies on udp-server and udp-core:

rest-api-core

Production imports in src/container.rs and src/statistics/services.rs:

Import Location
BanService container.rs
UdpTrackerCoreContainer container.rs
UdpTrackerServerContainer container.rs
udp_stats_repository types (Repository) container.rs
BanService statistics/services
udp_server::statistics statistics/services

Test-only imports (follow from production deps):

Import Concern
MAX_CONNECTION_ID_ERRORS_PER_IP Test ban init constant
BanService (concrete) Test BanService constructor

axum-rest-api-server

Production imports in src/v1/context/stats/handlers.rs:

Import Concern
BanService Handler state type
torrust_tracker_udp_server::statistics::repository::Repository Handler state type (get_stats)
torrust_tracker_udp_core::statistics::repository::Repository Handler state type (get_metrics)

Production references in src/v1/context/stats/routes.rs:

Reference Concern
http_api_container.ban_service Passed into handler state
http_api_container.udp_server_stats_repository Passed into handler state
http_api_container.udp_core_stats_repository Passed into handler state

Consequence

Both rest-api-core/Cargo.toml and axum-rest-api-server/Cargo.toml list udp-server and udp-core as runtime dependencies. After the decoupling, they can be demoted to dev-dependencies (or removed entirely) in both files.

Scope

1. Add decisions to DECISIONS.md

Record the next DEC number with the chosen approaches.

2. Trait extraction

Define shared trait abstractions for the three concrete UDP types that leak into REST code:

Trait Extracted from Host location (suggested)
BanningService (or similar) BanService (concrete struct) tracker-core or new primitives submodule
UdpCoreStatsRepository udp_tracker_core::statistics::repository::Repository tracker-core or new primitives submodule
UdpServerStatsRepository udp_server::statistics::repository::Repository tracker-core or new primitives submodule

Each trait exposes only the methods the REST layer actually calls. This keeps the interface minimal and avoids leaking UDP internals.

3. Turn MAX_CONNECTION_ID_ERRORS_PER_IP into a configuration option

Move MAX_CONNECTION_ID_ERRORS_PER_IP from a hardcoded pub const in udp_core to a new config field in the UdpTracker configuration struct (packages/configuration/src/v2_0_0/udp_tracker.rs):

  • Add field pub max_connection_id_errors_per_ip: u32 with default 10 via #[serde(default)].
  • UdpTrackerCoreContainer already holds Arc<UdpTracker>, so container.rs reads udp_tracker_config.max_connection_id_errors_per_ip instead of the constant.
  • Tests in rest-api-core use a literal 10 (or a local test constant) instead of importing MAX_CONNECTION_ID_ERRORS_PER_IP from udp_core.

4. Update rest-api-core

  • src/container.rs: TrackerHttpApiCoreContainer stores Arc<dyn BanningService> instead of Arc<RwLock<BanService>>, and Arc<dyn UdpStatsRepository> for stats repos. UdpTrackerCoreContainer and UdpTrackerServerContainer are no longer imported.
  • src/statistics/services.rs: function signatures use trait references instead of concrete udp_server_statistics::repository::Repository.
  • Test code: instantiate concrete types via udp_core / udp_server (dev-deps).
  • Cargo.toml: demote udp-server and udp-core to [dev-dependencies].

5. Update udp-server and udp-core

  • Implement the new traits on their existing concrete types.
  • The BanService struct gets impl BanningService for BanService.

6. Update axum-rest-api-server handlers and routes

  • src/v1/context/stats/handlers.rs: State tuples use Arc<dyn BanningService> and Arc<dyn UdpStatsRepository> instead of concrete types. The use imports for UDP concrete types are removed.
  • src/v1/context/stats/routes.rs: Routes pass trait objects from TrackerHttpApiCoreContainer fields (already trait objects after step 4).
  • Cargo.toml: demote udp-server and udp-core to [dev-dependencies].

7. Clean up

  • Run cargo machete to verify unused deps are gone from both Cargo.tomls.
  • Verify linter all and cargo test --workspace.

Acceptance Criteria

  1. rest-api-core/Cargo.toml has no udp-server or udp-core runtime dependency.
  2. axum-rest-api-server/Cargo.toml has no udp-server or udp-core runtime dependency.
  3. rest-api-core/src/ imports only trait abstractions from UDP packages, not concrete types.
  4. axum-rest-api-server/src/v1/context/stats/ uses trait objects in handler state tuples and routes, not concrete UDP types.
  5. cargo test --workspace passes.
  6. cargo machete passes.
  7. linter all passes.

Out of Scope

  • Extracting any UDP package to a standalone repository.
  • Changing the HTTP tracker side of the REST layer.
  • Relocating test environments (already done in SI-23/SI-24/SI-25).

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions