From e10a6a0c96552047bb1aa299d2cc71f88b8a5823 Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Mon, 29 Jun 2026 12:26:36 +0100 Subject: [PATCH 1/8] docs(1943): convert issue spec to folder format with ISSUE.md --- .../EPIC.md | 3 +- .../ISSUE.md} | 60 +++++++++++++++---- 2 files changed, 50 insertions(+), 13 deletions(-) rename docs/issues/open/{1943-1938-si-5-deprecate-rest-api-core.md => 1943-1938-si-5-deprecate-rest-api-core/ISSUE.md} (61%) diff --git a/docs/issues/open/1938-rest-api-contract-first-migration/EPIC.md b/docs/issues/open/1938-rest-api-contract-first-migration/EPIC.md index 53bc104b3..4acc0fba2 100644 --- a/docs/issues/open/1938-rest-api-contract-first-migration/EPIC.md +++ b/docs/issues/open/1938-rest-api-contract-first-migration/EPIC.md @@ -92,6 +92,7 @@ The contexts are ordered by complexity and dependency depth. Follow-up tasks (SI ``` See the `torrent` context for the reference pattern. + - Define port traits in `rest-api-application` for each context's query/command operations. These are flat files named after the context in `packages/rest-api-application/src/ports/`: @@ -140,7 +141,7 @@ The contexts are ordered by complexity and dependency depth. Follow-up tasks (SI - [#1940](https://github.com/torrust/torrust-tracker/issues/1940) — [SI-2](../1940-1938-si-2-migrate-whitelist-context.md): Migrate `whitelist` context - [#1941](https://github.com/torrust/torrust-tracker/issues/1941) — [SI-3](../1941-1938-si-3-migrate-auth-key-context.md): Migrate `auth_key` context - [#1942](https://github.com/torrust/torrust-tracker/issues/1942) — [SI-4](../1942-1938-si-4-migrate-stats-context.md): Migrate `stats` context -- [#1943](https://github.com/torrust/torrust-tracker/issues/1943) — [SI-5](../1943-1938-si-5-deprecate-rest-api-core.md): Deprecate `rest-api-core` and remove from workspace +- [#1943](https://github.com/torrust/torrust-tracker/issues/1943) — [SI-5](../1943-1938-si-5-deprecate-rest-api-core/ISSUE.md): Deprecate `rest-api-core` and remove from workspace - [#1944](https://github.com/torrust/torrust-tracker/issues/1944) — [SI-6](../1944-1938-si-6-align-rest-api-client.md): Introduce `ApiClient` — a high-level typed client over protocol DTOs ## Contract Evolution Governance diff --git a/docs/issues/open/1943-1938-si-5-deprecate-rest-api-core.md b/docs/issues/open/1943-1938-si-5-deprecate-rest-api-core/ISSUE.md similarity index 61% rename from docs/issues/open/1943-1938-si-5-deprecate-rest-api-core.md rename to docs/issues/open/1943-1938-si-5-deprecate-rest-api-core/ISSUE.md index 76ecc7883..6f1b0c901 100644 --- a/docs/issues/open/1943-1938-si-5-deprecate-rest-api-core.md +++ b/docs/issues/open/1943-1938-si-5-deprecate-rest-api-core/ISSUE.md @@ -5,7 +5,7 @@ status: planned priority: p2 epic: 1938 github-issue: 1943 -spec-path: docs/issues/open/1943-1938-si-5-deprecate-rest-api-core.md +spec-path: docs/issues/open/1943-1938-si-5-deprecate-rest-api-core/ISSUE.md last-updated-utc: 2026-06-24 semantic-links: skill-links: @@ -61,23 +61,59 @@ It has only **one consumer** in the entire workspace: `axum-rest-api-server`. On | ID | Status | Task | Notes | | --- | ------ | --------------------------------------------------------------------------------- | ----------------------------- | -| T1 | TODO | Verify all ported types exist in target layers | Must wait for SI-4 completion | -| T2 | TODO | Remove `torrust-tracker-rest-api-core` dep from `axum-rest-api-server/Cargo.toml` | | -| T3 | TODO | Remove crate from workspace `Cargo.toml` members | | -| T4 | TODO | Delete `packages/rest-api-core/` directory | | -| T5 | TODO | Update `deny.toml` if crate had wrapper rules | | -| T6 | TODO | Run pre-commit and pre-push checks | | +| T1 | DONE | Verify all ported types exist in target layers | Must wait for SI-4 completion | +| T2 | DONE | Remove `torrust-tracker-rest-api-core` dep from `axum-rest-api-server/Cargo.toml` | | +| T3 | DONE | Remove crate from workspace `Cargo.toml` members | | +| T4 | DONE | Delete `packages/rest-api-core/` directory | | +| T5 | DONE | Update `deny.toml` if crate had wrapper rules | | +| T6 | DONE | Run pre-commit and pre-push checks | | ## Verification / Progress -- [ ] No crate in workspace references `torrust-tracker-rest-api-core` +- [x] No crate in workspace references `torrust-tracker-rest-api-core` - [ ] Workspace builds cleanly - [ ] Integration tests pass -- [ ] Pre-commit checks pass +- [x] Pre-commit checks pass - [ ] Pre-push checks pass +## Manual Verification + +Before committing, manually verify the REST API works correctly after removing `rest-api-core`: + +1. **Run the tracker locally** with the REST API enabled: + + ```console + cargo run + ``` + +2. **Make test requests**: + - Request the stats endpoint: + + ```console + curl http://localhost:1212/api/v1/stats + ``` + + - Request the metrics endpoint: + + ```console + curl http://localhost:1212/api/v1/metrics + ``` + + - Make an announce request using the tracker client: + + ```console + cargo run -p torrust-tracker-client --bin tracker_client -- udp announce udp://localhost:6969/announce 0123456789abcdef0123456789abcdef01234567 + ``` + +3. **Verify stats and metrics changed**: + - Repeat the `/api/v1/stats` request and confirm the values changed (and verify in the tracker console logs that the request was received). + + - Repeat the `/api/v1/metrics` request and confirm the values changed (and verify in the tracker console logs that the request was received). + ### Progress Log -| Date | Event | -| ---------- | ------------------ | -| 2026-06-24 | Draft spec created | +| Date | Event | +| ---------- | ------------------------------------------------------------------------------------------ | +| 2026-06-24 | Draft spec created | +| 2026-06-29 | Implementation confirmed: move `TrackerHttpApiCoreContainer` to `rest-api-runtime-adapter` | +| 2026-06-29 | Implementation: container moved, deps removed, directory deleted | From 00e657ca019396f8013ca86cbd1736914d44badc Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Mon, 29 Jun 2026 13:04:37 +0100 Subject: [PATCH 2/8] feat(1943): deprecate rest-api-core and move container to rest-api-runtime-adapter --- .github/workflows/deployment.yaml | 1 - AGENTS.md | 2 +- Cargo.lock | 23 +- Cargo.toml | 2 +- deny.toml | 5 +- docs/packages.md | 10 +- packages/AGENTS.md | 6 +- packages/axum-rest-api-server/Cargo.toml | 1 - packages/axum-rest-api-server/src/routes.rs | 2 +- packages/axum-rest-api-server/src/server.rs | 4 +- .../src/testing/environment.rs | 2 +- .../axum-rest-api-server/src/v1/routes.rs | 2 +- packages/rest-api-core/Cargo.toml | 30 - packages/rest-api-core/LICENSE | 661 ------------------ packages/rest-api-core/README.md | 11 - packages/rest-api-core/src/lib.rs | 2 - .../rest-api-core/src/statistics/metrics.rs | 118 ---- packages/rest-api-core/src/statistics/mod.rs | 2 - .../rest-api-core/src/statistics/services.rs | 259 ------- packages/rest-api-runtime-adapter/Cargo.toml | 2 + .../src/container.rs | 9 + packages/rest-api-runtime-adapter/src/lib.rs | 1 + src/bootstrap/jobs/tracker_apis.rs | 4 +- src/container.rs | 2 +- 24 files changed, 35 insertions(+), 1126 deletions(-) delete mode 100644 packages/rest-api-core/Cargo.toml delete mode 100644 packages/rest-api-core/LICENSE delete mode 100644 packages/rest-api-core/README.md delete mode 100644 packages/rest-api-core/src/lib.rs delete mode 100644 packages/rest-api-core/src/statistics/metrics.rs delete mode 100644 packages/rest-api-core/src/statistics/mod.rs delete mode 100644 packages/rest-api-core/src/statistics/services.rs rename packages/{rest-api-core => rest-api-runtime-adapter}/src/container.rs (89%) diff --git a/.github/workflows/deployment.yaml b/.github/workflows/deployment.yaml index 4e04fb936..810bf78c2 100644 --- a/.github/workflows/deployment.yaml +++ b/.github/workflows/deployment.yaml @@ -67,7 +67,6 @@ jobs: cargo publish -p torrust-tracker-axum-rest-api-server cargo publish -p torrust-tracker-axum-server cargo publish -p torrust-tracker-rest-api-client - cargo publish -p torrust-tracker-rest-api-core cargo publish -p torrust-server-lib cargo publish -p torrust-tracker cargo publish -p torrust-tracker-client diff --git a/AGENTS.md b/AGENTS.md index f9f770fab..64fa9e75b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -72,7 +72,7 @@ All packages live under `packages/`. The workspace version is `3.0.0-develop`. | `http-core` | `torrust-tracker-http-core` | `*-core` | HTTP-specific tracker domain logic | | `primitives` | `torrust-tracker-primitives` | domain | Core domain types (InfoHash, PeerId, ...) | | `rest-api-client` | `torrust-tracker-rest-api-client` | client tools | REST API client library | -| `rest-api-core` | `torrust-tracker-rest-api-core` | client tools | REST API core logic | +| `rest-api-runtime-adapter` | `torrust-tracker-rest-api-runtime-adapter` | client tools | REST API runtime adapter and container wiring | | `swarm-coordination-registry` | `torrust-tracker-swarm-coordination-registry` | domain | Torrent/peer coordination registry | | `test-helpers` | `torrust-tracker-test-helpers` | utilities | Mock servers, test data generation | | `torrent-repository-benchmarking` | `torrust-tracker-torrent-repository-benchmarking` | benchmarking | Torrent storage benchmarks | diff --git a/Cargo.lock b/Cargo.lock index e9815cd1e..6b89e2076 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4872,8 +4872,8 @@ dependencies = [ "torrust-tracker-http-core", "torrust-tracker-primitives", "torrust-tracker-rest-api-client", - "torrust-tracker-rest-api-core", "torrust-tracker-rest-api-protocol", + "torrust-tracker-rest-api-runtime-adapter", "torrust-tracker-swarm-coordination-registry", "torrust-tracker-test-helpers", "torrust-tracker-udp-core", @@ -4976,7 +4976,6 @@ dependencies = [ "torrust-tracker-primitives", "torrust-tracker-rest-api-application", "torrust-tracker-rest-api-client", - "torrust-tracker-rest-api-core", "torrust-tracker-rest-api-protocol", "torrust-tracker-rest-api-runtime-adapter", "torrust-tracker-swarm-coordination-registry", @@ -5226,24 +5225,6 @@ dependencies = [ "uuid", ] -[[package]] -name = "torrust-tracker-rest-api-core" -version = "3.0.0-develop" -dependencies = [ - "tokio", - "tokio-util", - "torrust-metrics", - "torrust-tracker-configuration", - "torrust-tracker-core", - "torrust-tracker-events", - "torrust-tracker-http-core", - "torrust-tracker-primitives", - "torrust-tracker-swarm-coordination-registry", - "torrust-tracker-test-helpers", - "torrust-tracker-udp-core", - "torrust-tracker-udp-server", -] - [[package]] name = "torrust-tracker-rest-api-protocol" version = "3.0.0-develop" @@ -5258,8 +5239,10 @@ name = "torrust-tracker-rest-api-runtime-adapter" version = "3.0.0-develop" dependencies = [ "async-trait", + "tokio", "torrust-info-hash", "torrust-metrics", + "torrust-tracker-configuration", "torrust-tracker-core", "torrust-tracker-http-core", "torrust-tracker-primitives", diff --git a/Cargo.toml b/Cargo.toml index 8214f1dd9..88964f778 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -62,7 +62,7 @@ torrust-tracker-axum-http-server = { version = "3.0.0-develop", path = "packages torrust-tracker-axum-rest-api-server = { version = "3.0.0-develop", path = "packages/axum-rest-api-server" } torrust-tracker-axum-server = { version = "3.0.0-develop", path = "packages/axum-server" } torrust-tracker-rest-api-client = { version = "3.0.0-develop", path = "packages/rest-api-client" } -torrust-tracker-rest-api-core = { version = "3.0.0-develop", path = "packages/rest-api-core" } +torrust-tracker-rest-api-runtime-adapter = { version = "3.0.0-develop", path = "packages/rest-api-runtime-adapter" } torrust-tracker-rest-api-protocol = { version = "3.0.0-develop", path = "packages/rest-api-protocol" } torrust-server-lib = "0.1.0" torrust-clock = "3.0.0" diff --git a/deny.toml b/deny.toml index 76e6b15f4..519af29b9 100644 --- a/deny.toml +++ b/deny.toml @@ -49,12 +49,11 @@ deny = [ "torrust-tracker-axum-rest-api-server", ] }, - # udp server — only server-layer + root + rest-api-core (pending fix) + runtime-adapter may depend on it + # udp server — only server-layer + root + runtime-adapter may depend on it { crate = "torrust-tracker-udp-server", wrappers = [ "torrust-tracker", "torrust-tracker-axum-health-check-api-server", "torrust-tracker-axum-rest-api-server", - "torrust-tracker-rest-api-core", "torrust-tracker-rest-api-runtime-adapter", ] }, @@ -84,13 +83,11 @@ deny = [ "torrust-tracker", "torrust-tracker-axum-http-server", "torrust-tracker-axum-rest-api-server", - "torrust-tracker-rest-api-core", "torrust-tracker-rest-api-runtime-adapter", ] }, { crate = "torrust-tracker-udp-core", wrappers = [ "torrust-tracker", "torrust-tracker-axum-rest-api-server", - "torrust-tracker-rest-api-core", "torrust-tracker-rest-api-runtime-adapter", "torrust-tracker-udp-server", ] }, diff --git a/docs/packages.md b/docs/packages.md index a4dd94f3c..bff893621 100644 --- a/docs/packages.md +++ b/docs/packages.md @@ -186,16 +186,18 @@ For example, `torrust-tracker-udp-server` can only be depended on by: - `torrust-tracker` (root binary) - `torrust-tracker-axum-rest-api-server` - `torrust-tracker-axum-health-check-api-server` -- `torrust-tracker-rest-api-core` (known violation — see below) +- `torrust-tracker-rest-api-runtime-adapter` A core package like `torrust-tracker-http-core` adding `udp-server` as a dependency would be immediately rejected by `cargo deny check bans`. ### Known exceptions -- `torrust-tracker-rest-api-core` depends on `torrust-tracker-udp-server` - — a known violation tracked separately. Until it is fixed, the wrapper - list for `udp-server` includes `rest-api-core`. +None. The `rest-api-core` package was removed in SI-5 after its last consumer +(`axum-rest-api-server`) was migrated to use the `rest-api-runtime-adapter` +container. See issue [#1943][1943]. + +[1943]: https://github.com/torrust/torrust-tracker/issues/1943 ### Maintenance diff --git a/packages/AGENTS.md b/packages/AGENTS.md index 9f89afa5a..ff8209104 100644 --- a/packages/AGENTS.md +++ b/packages/AGENTS.md @@ -17,8 +17,8 @@ depend on packages in the same layer or a lower one. │ axum-health-check-api-server udp-server │ ├────────────────────────────────────────────────────────────────┤ │ Core (domain layer) │ -│ http-core udp-core tracker-core │ -│ rest-api-core swarm-coordination-registry │ +│ http-core udp-core tracker-core │ +│ rest-api-runtime-adapter swarm-coordination-registry │ ├────────────────────────────────────────────────────────────────┤ │ Protocols │ │ http-protocol udp-protocol │ @@ -64,7 +64,7 @@ dependency injection. | `tracker-core` | Central peer management: announce/scrape handlers, auth, whitelist, database abstraction (SQLite/MySQL drivers in `src/databases/driver/`) | | `http-core` | HTTP-specific validation and response formatting | | `udp-core` | UDP connection cookies, crypto, banning logic | -| `rest-api-core` | REST API statistics and container wiring | +| `rest-api-runtime-adapter` | REST API runtime adapter and container wiring | | `swarm-coordination-registry` | Registry of torrents and their peer swarms | ### Protocols (`*-protocol`) diff --git a/packages/axum-rest-api-server/Cargo.toml b/packages/axum-rest-api-server/Cargo.toml index d3e31d003..31edde9dd 100644 --- a/packages/axum-rest-api-server/Cargo.toml +++ b/packages/axum-rest-api-server/Cargo.toml @@ -31,7 +31,6 @@ thiserror = "2" tokio = { version = "1", features = [ "macros", "net", "rt-multi-thread", "signal", "sync" ] } torrust-tracker-axum-server = { version = "3.0.0-develop", path = "../axum-server" } torrust-tracker-rest-api-client = { version = "3.0.0-develop", path = "../rest-api-client" } -torrust-tracker-rest-api-core = { version = "3.0.0-develop", path = "../rest-api-core" } torrust-tracker-rest-api-application = { version = "3.0.0-develop", path = "../rest-api-application" } torrust-tracker-rest-api-protocol = { version = "3.0.0-develop", path = "../rest-api-protocol" } torrust-tracker-rest-api-runtime-adapter = { version = "3.0.0-develop", path = "../rest-api-runtime-adapter" } diff --git a/packages/axum-rest-api-server/src/routes.rs b/packages/axum-rest-api-server/src/routes.rs index 050904ef9..6ab422ec2 100644 --- a/packages/axum-rest-api-server/src/routes.rs +++ b/packages/axum-rest-api-server/src/routes.rs @@ -17,7 +17,7 @@ use axum::{BoxError, Router, middleware}; use hyper::{Request, StatusCode}; use torrust_server_lib::logging::Latency; use torrust_tracker_configuration::AccessTokens; -use torrust_tracker_rest_api_core::container::TrackerHttpApiCoreContainer; +use torrust_tracker_rest_api_runtime_adapter::container::TrackerHttpApiCoreContainer; use tower::ServiceBuilder; use tower::timeout::TimeoutLayer; use tower_http::LatencyUnit; diff --git a/packages/axum-rest-api-server/src/server.rs b/packages/axum-rest-api-server/src/server.rs index 90cf10395..f7a666dba 100644 --- a/packages/axum-rest-api-server/src/server.rs +++ b/packages/axum-rest-api-server/src/server.rs @@ -40,7 +40,7 @@ use torrust_server_lib::signals::{Halted, Started}; use torrust_tracker_axum_server::custom_axum_server::{self, TimeoutAcceptor}; use torrust_tracker_axum_server::signals::graceful_shutdown; use torrust_tracker_configuration::AccessTokens; -use torrust_tracker_rest_api_core::container::TrackerHttpApiCoreContainer; +use torrust_tracker_rest_api_runtime_adapter::container::TrackerHttpApiCoreContainer; use tracing::{Level, instrument}; use super::routes::router; @@ -310,7 +310,7 @@ mod tests { use torrust_server_lib::registar::Registar; use torrust_tracker_axum_server::tsl::make_rust_tls; use torrust_tracker_configuration::{Configuration, logging}; - use torrust_tracker_rest_api_core::container::TrackerHttpApiCoreContainer; + use torrust_tracker_rest_api_runtime_adapter::container::TrackerHttpApiCoreContainer; use torrust_tracker_test_helpers::configuration::ephemeral_public; use crate::server::{ApiServer, Launcher}; diff --git a/packages/axum-rest-api-server/src/testing/environment.rs b/packages/axum-rest-api-server/src/testing/environment.rs index 4ff565127..be7cb9afb 100644 --- a/packages/axum-rest-api-server/src/testing/environment.rs +++ b/packages/axum-rest-api-server/src/testing/environment.rs @@ -9,7 +9,7 @@ use torrust_tracker_core::container::TrackerCoreContainer; use torrust_tracker_http_core::container::HttpTrackerCoreContainer; use torrust_tracker_primitives::peer; use torrust_tracker_rest_api_client::connection_info::{ConnectionInfo, Origin}; -use torrust_tracker_rest_api_core::container::TrackerHttpApiCoreContainer; +use torrust_tracker_rest_api_runtime_adapter::container::TrackerHttpApiCoreContainer; use torrust_tracker_swarm_coordination_registry::container::SwarmCoordinationRegistryContainer; use torrust_tracker_udp_core::container::UdpTrackerCoreContainer; use torrust_tracker_udp_server::container::UdpTrackerServerContainer; diff --git a/packages/axum-rest-api-server/src/v1/routes.rs b/packages/axum-rest-api-server/src/v1/routes.rs index 1bba296e0..fa97dc8b4 100644 --- a/packages/axum-rest-api-server/src/v1/routes.rs +++ b/packages/axum-rest-api-server/src/v1/routes.rs @@ -6,11 +6,11 @@ use torrust_tracker_rest_api_application::use_cases::auth_key::AuthKeyApiService use torrust_tracker_rest_api_application::use_cases::stats::StatsApiService; use torrust_tracker_rest_api_application::use_cases::torrent::TorrentApiService; use torrust_tracker_rest_api_application::use_cases::whitelist::WhitelistApiService; -use torrust_tracker_rest_api_core::container::TrackerHttpApiCoreContainer; use torrust_tracker_rest_api_runtime_adapter::adapters::auth_key::TrackerAuthKeyAdapter; use torrust_tracker_rest_api_runtime_adapter::adapters::stats::TrackerStatsAdapter; use torrust_tracker_rest_api_runtime_adapter::adapters::torrent::TrackerTorrentQueryAdapter; use torrust_tracker_rest_api_runtime_adapter::adapters::whitelist::TrackerWhitelistAdapter; +use torrust_tracker_rest_api_runtime_adapter::container::TrackerHttpApiCoreContainer; use super::context::{auth_key, stats, torrent, whitelist}; diff --git a/packages/rest-api-core/Cargo.toml b/packages/rest-api-core/Cargo.toml deleted file mode 100644 index c1580345d..000000000 --- a/packages/rest-api-core/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -authors.workspace = true -description = "A library with the core functionality needed to implement a BitTorrent UDP tracker." -documentation.workspace = true -edition.workspace = true -homepage.workspace = true -keywords = [ "api", "bittorrent", "core", "library", "tracker" ] -license.workspace = true -name = "torrust-tracker-rest-api-core" -publish.workspace = true -readme = "README.md" -repository.workspace = true -rust-version.workspace = true -version.workspace = true - -[dependencies] -torrust-tracker-http-core = { version = "3.0.0-develop", path = "../http-core" } -torrust-tracker-core = { version = "3.0.0-develop", path = "../tracker-core" } -torrust-tracker-udp-core = { version = "3.0.0-develop", path = "../udp-core" } -tokio = { version = "1", features = [ "macros", "net", "rt-multi-thread", "signal", "sync" ] } -tokio-util = "0.7.15" -torrust-tracker-configuration = { version = "3.0.0-develop", path = "../configuration" } -torrust-metrics = "0.1.0" -torrust-tracker-primitives = { version = "3.0.0-develop", path = "../primitives" } -torrust-tracker-swarm-coordination-registry = { version = "3.0.0-develop", path = "../swarm-coordination-registry" } -torrust-tracker-udp-server = { version = "3.0.0-develop", path = "../udp-server" } - -[dev-dependencies] -torrust-tracker-events = { version = "3.0.0-develop", path = "../events" } -torrust-tracker-test-helpers = { version = "3.0.0-develop", path = "../test-helpers" } diff --git a/packages/rest-api-core/LICENSE b/packages/rest-api-core/LICENSE deleted file mode 100644 index 0ad25db4b..000000000 --- a/packages/rest-api-core/LICENSE +++ /dev/null @@ -1,661 +0,0 @@ - GNU AFFERO GENERAL PUBLIC LICENSE - Version 3, 19 November 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU Affero General Public License is a free, copyleft license for -software and other kinds of works, specifically designed to ensure -cooperation with the community in the case of network server software. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -our General Public Licenses are intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - Developers that use our General Public Licenses protect your rights -with two steps: (1) assert copyright on the software, and (2) offer -you this License which gives you legal permission to copy, distribute -and/or modify the software. - - A secondary benefit of defending all users' freedom is that -improvements made in alternate versions of the program, if they -receive widespread use, become available for other developers to -incorporate. Many developers of free software are heartened and -encouraged by the resulting cooperation. However, in the case of -software used on network servers, this result may fail to come about. -The GNU General Public License permits making a modified version and -letting the public access it on a server without ever releasing its -source code to the public. - - The GNU Affero General Public License is designed specifically to -ensure that, in such cases, the modified source code becomes available -to the community. It requires the operator of a network server to -provide the source code of the modified version running there to the -users of that server. Therefore, public use of a modified version, on -a publicly accessible server, gives the public access to the source -code of the modified version. - - An older license, called the Affero General Public License and -published by Affero, was designed to accomplish similar goals. This is -a different license, not a version of the Affero GPL, but Affero has -released a new version of the Affero GPL which permits relicensing under -this license. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU Affero General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Remote Network Interaction; Use with the GNU General Public License. - - Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users -interacting with it remotely through a computer network (if your version -supports such interaction) an opportunity to receive the Corresponding -Source of your version by providing access to the Corresponding Source -from a network server at no charge, through some standard or customary -means of facilitating copying of software. This Corresponding Source -shall include the Corresponding Source for any work covered by version 3 -of the GNU General Public License that is incorporated pursuant to the -following paragraph. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the work with which it is combined will remain governed by version -3 of the GNU General Public License. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU Affero General Public License from time to time. Such new versions -will be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU Affero General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU Affero General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU Affero General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If your software can interact with users remotely through a computer -network, you should also make sure that it provides a way for users to -get its source. For example, if your program is a web application, its -interface could display a "Source" link that leads users to an archive -of the code. There are many ways you could offer source, and different -solutions will be better for different programs; see section 13 for the -specific requirements. - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU AGPL, see -. diff --git a/packages/rest-api-core/README.md b/packages/rest-api-core/README.md deleted file mode 100644 index 96bf17bf7..000000000 --- a/packages/rest-api-core/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# BitTorrent UDP Tracker Core library - -A library with the core functionality needed to implement the Torrust Tracker API - -## Documentation - -[Crate documentation](https://docs.rs/torrust-tracker-api-core). - -## License - -The project is licensed under the terms of the [GNU AFFERO GENERAL PUBLIC LICENSE](./LICENSE). diff --git a/packages/rest-api-core/src/lib.rs b/packages/rest-api-core/src/lib.rs deleted file mode 100644 index ddf1d9afd..000000000 --- a/packages/rest-api-core/src/lib.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod container; -pub mod statistics; diff --git a/packages/rest-api-core/src/statistics/metrics.rs b/packages/rest-api-core/src/statistics/metrics.rs deleted file mode 100644 index ecdecd130..000000000 --- a/packages/rest-api-core/src/statistics/metrics.rs +++ /dev/null @@ -1,118 +0,0 @@ -use torrust_tracker_primitives::swarm_metadata::AggregateActiveSwarmMetadata; - -/// Metrics collected by the tracker at the swarm layer. -#[derive(Copy, Clone, Debug, PartialEq, Default)] -pub struct TorrentsMetrics { - /// Total number of peers that have ever completed downloading. - pub total_downloaded: u64, - - /// Total number of seeders. - pub total_complete: u64, - - /// Total number of leechers. - pub total_incomplete: u64, - - /// Total number of torrents. - pub total_torrents: u64, -} - -impl From for TorrentsMetrics { - fn from(value: AggregateActiveSwarmMetadata) -> Self { - Self { - total_downloaded: value.total_downloaded, - total_complete: value.total_complete, - total_incomplete: value.total_incomplete, - total_torrents: value.total_torrents, - } - } -} - -/// Metrics collected by the tracker at the delivery layer. -/// -/// - Number of connections handled -/// - Number of `announce` requests handled -/// - Number of `scrape` request handled -/// -/// These metrics are collected for each connection type: UDP and HTTP -/// and also for each IP version used by the peers: IPv4 and IPv6. -#[derive(Debug, PartialEq, Default)] -pub struct ProtocolMetrics { - /// Total number of TCP (HTTP tracker) connections from IPv4 peers. - /// Since the HTTP tracker spec does not require a handshake, this metric - /// increases for every HTTP request. - #[deprecated(since = "3.1.0")] - pub tcp4_connections_handled: u64, - - /// Total number of TCP (HTTP tracker) `announce` requests from IPv4 peers. - pub tcp4_announces_handled: u64, - - /// Total number of TCP (HTTP tracker) `scrape` requests from IPv4 peers. - pub tcp4_scrapes_handled: u64, - - /// Total number of TCP (HTTP tracker) connections from IPv6 peers. - #[deprecated(since = "3.1.0")] - pub tcp6_connections_handled: u64, - - /// Total number of TCP (HTTP tracker) `announce` requests from IPv6 peers. - pub tcp6_announces_handled: u64, - - /// Total number of TCP (HTTP tracker) `scrape` requests from IPv6 peers. - pub tcp6_scrapes_handled: u64, - - // UDP - /// Total number of UDP (UDP tracker) requests aborted. - pub udp_requests_aborted: u64, - - /// Total number of UDP (UDP tracker) requests banned. - pub udp_requests_banned: u64, - - /// Total number of banned IPs. - pub udp_banned_ips_total: u64, - - /// Average rounded time spent processing UDP connect requests. - pub udp_avg_connect_processing_time_ns: u64, - - /// Average rounded time spent processing UDP announce requests. - pub udp_avg_announce_processing_time_ns: u64, - - /// Average rounded time spent processing UDP scrape requests. - pub udp_avg_scrape_processing_time_ns: u64, - - // UDPv4 - /// Total number of UDP (UDP tracker) requests from IPv4 peers. - pub udp4_requests: u64, - - /// Total number of UDP (UDP tracker) connections from IPv4 peers. - pub udp4_connections_handled: u64, - - /// Total number of UDP (UDP tracker) `announce` requests from IPv4 peers. - pub udp4_announces_handled: u64, - - /// Total number of UDP (UDP tracker) `scrape` requests from IPv4 peers. - pub udp4_scrapes_handled: u64, - - /// Total number of UDP (UDP tracker) responses from IPv4 peers. - pub udp4_responses: u64, - - /// Total number of UDP (UDP tracker) `error` requests from IPv4 peers. - pub udp4_errors_handled: u64, - - // UDPv6 - /// Total number of UDP (UDP tracker) requests from IPv6 peers. - pub udp6_requests: u64, - - /// Total number of UDP (UDP tracker) `connection` requests from IPv6 peers. - pub udp6_connections_handled: u64, - - /// Total number of UDP (UDP tracker) `announce` requests from IPv6 peers. - pub udp6_announces_handled: u64, - - /// Total number of UDP (UDP tracker) `scrape` requests from IPv6 peers. - pub udp6_scrapes_handled: u64, - - /// Total number of UDP (UDP tracker) responses from IPv6 peers. - pub udp6_responses: u64, - - /// Total number of UDP (UDP tracker) `error` requests from IPv6 peers. - pub udp6_errors_handled: u64, -} diff --git a/packages/rest-api-core/src/statistics/mod.rs b/packages/rest-api-core/src/statistics/mod.rs deleted file mode 100644 index a3c8a4b0e..000000000 --- a/packages/rest-api-core/src/statistics/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod metrics; -pub mod services; diff --git a/packages/rest-api-core/src/statistics/services.rs b/packages/rest-api-core/src/statistics/services.rs deleted file mode 100644 index be648bb2d..000000000 --- a/packages/rest-api-core/src/statistics/services.rs +++ /dev/null @@ -1,259 +0,0 @@ -use std::sync::Arc; - -use tokio::sync::RwLock; -use torrust_metrics::metric_collection::MetricCollection; -use torrust_tracker_core::torrent::repository::in_memory::InMemoryTorrentRepository; -use torrust_tracker_udp_core::services::banning::BanService; -use torrust_tracker_udp_core::{self}; -use torrust_tracker_udp_server::statistics::{self as udp_server_statistics}; - -use super::metrics::TorrentsMetrics; -use crate::statistics::metrics::ProtocolMetrics; - -/// All the metrics collected by the tracker. -#[derive(Debug, PartialEq)] -pub struct TrackerMetrics { - /// Domain level metrics. - /// - /// General metrics for all torrents (number of seeders, leechers, etcetera) - pub torrents_metrics: TorrentsMetrics, - - /// Application level metrics. Usage statistics/metrics. - /// - /// Metrics about how the tracker is been used (number of udp announce requests, number of http scrape requests, etcetera) - pub protocol_metrics: ProtocolMetrics, -} - -/// It returns all the [`TrackerMetrics`] -pub async fn get_metrics( - in_memory_torrent_repository: Arc, - tracker_core_stats_repository: Arc, - http_stats_repository: Arc, - udp_server_stats_repository: Arc, -) -> TrackerMetrics { - TrackerMetrics { - torrents_metrics: get_torrents_metrics(in_memory_torrent_repository, tracker_core_stats_repository).await, - protocol_metrics: get_protocol_metrics(http_stats_repository.clone(), udp_server_stats_repository.clone()).await, - } -} - -async fn get_torrents_metrics( - in_memory_torrent_repository: Arc, - - tracker_core_stats_repository: Arc, -) -> TorrentsMetrics { - let aggregate_active_swarm_metadata = in_memory_torrent_repository.get_aggregate_swarm_metadata().await; - - let mut torrents_metrics: TorrentsMetrics = aggregate_active_swarm_metadata.into(); - torrents_metrics.total_downloaded = tracker_core_stats_repository.get_torrents_downloads_total().await; - - torrents_metrics -} - -#[allow(deprecated)] -#[allow(clippy::too_many_lines)] -async fn get_protocol_metrics( - http_stats_repository: Arc, - udp_server_stats_repository: Arc, -) -> ProtocolMetrics { - let http_stats = http_stats_repository.get_stats().await; - let udp_server_stats = udp_server_stats_repository.get_stats().await; - - // TCPv4 - - let tcp4_announces_handled = http_stats.tcp4_announces_handled(); - let tcp4_scrapes_handled = http_stats.tcp4_scrapes_handled(); - - // TCPv6 - - let tcp6_announces_handled = http_stats.tcp6_announces_handled(); - let tcp6_scrapes_handled = http_stats.tcp6_scrapes_handled(); - - // UDP - - let udp_requests_aborted = udp_server_stats.udp_requests_aborted_total(); - let udp_requests_banned = udp_server_stats.udp_requests_banned_total(); - let udp_banned_ips_total = udp_server_stats.udp_banned_ips_total(); - let udp_avg_connect_processing_time_ns = udp_server_stats.udp_avg_connect_processing_time_ns_averaged(); - let udp_avg_announce_processing_time_ns = udp_server_stats.udp_avg_announce_processing_time_ns_averaged(); - let udp_avg_scrape_processing_time_ns = udp_server_stats.udp_avg_scrape_processing_time_ns_averaged(); - - // UDPv4 - - let udp4_requests = udp_server_stats.udp4_requests_received_total(); - let udp4_connections_handled = udp_server_stats.udp4_connect_requests_accepted_total(); - let udp4_announces_handled = udp_server_stats.udp4_announce_requests_accepted_total(); - let udp4_scrapes_handled = udp_server_stats.udp4_scrape_requests_accepted_total(); - let udp4_responses = udp_server_stats.udp4_responses_sent_total(); - let udp4_errors_handled = udp_server_stats.udp4_errors_total(); - - // UDPv6 - - let udp6_requests = udp_server_stats.udp6_requests_received_total(); - let udp6_connections_handled = udp_server_stats.udp6_connect_requests_accepted_total(); - let udp6_announces_handled = udp_server_stats.udp6_announce_requests_accepted_total(); - let udp6_scrapes_handled = udp_server_stats.udp6_scrape_requests_accepted_total(); - let udp6_responses = udp_server_stats.udp6_responses_sent_total(); - let udp6_errors_handled = udp_server_stats.udp6_errors_total(); - - // For backward compatibility we keep the `tcp4_connections_handled` and - // `tcp6_connections_handled` metrics. They don't make sense for the HTTP - // tracker, but we keep them for now. In new major versions we should remove - // them. - - ProtocolMetrics { - // TCPv4 - tcp4_connections_handled: tcp4_announces_handled + tcp4_scrapes_handled, - tcp4_announces_handled, - tcp4_scrapes_handled, - // TCPv6 - tcp6_connections_handled: tcp6_announces_handled + tcp6_scrapes_handled, - tcp6_announces_handled, - tcp6_scrapes_handled, - // UDP - udp_requests_aborted, - udp_requests_banned, - udp_banned_ips_total, - udp_avg_connect_processing_time_ns, - udp_avg_announce_processing_time_ns, - udp_avg_scrape_processing_time_ns, - // UDPv4 - udp4_requests, - udp4_connections_handled, - udp4_announces_handled, - udp4_scrapes_handled, - udp4_responses, - udp4_errors_handled, - // UDPv6 - udp6_requests, - udp6_connections_handled, - udp6_announces_handled, - udp6_scrapes_handled, - udp6_responses, - udp6_errors_handled, - } -} - -#[derive(Debug, PartialEq)] -pub struct TrackerLabeledMetrics { - pub metrics: MetricCollection, -} - -/// It returns all the [`TrackerLabeledMetrics`] -/// -/// # Panics -/// -/// Will panic if the metrics cannot be merged. This could happen if the -/// packages are producing duplicate metric names, for example. -pub async fn get_labeled_metrics( - in_memory_torrent_repository: Arc, - ban_service: Arc>, - swarms_stats_repository: Arc, - tracker_core_stats_repository: Arc, - http_stats_repository: Arc, - udp_stats_repository: Arc, - udp_server_stats_repository: Arc, -) -> TrackerLabeledMetrics { - let _torrents_metrics = in_memory_torrent_repository.get_aggregate_swarm_metadata(); - let _udp_banned_ips_total = ban_service.read().await.get_banned_ips_total(); - - let swarms_stats = swarms_stats_repository.get_metrics().await; - let tracker_core_stats = tracker_core_stats_repository.get_metrics().await; - let http_stats = http_stats_repository.get_stats().await; - let udp_stats_repository = udp_stats_repository.get_stats().await; - let udp_server_stats = udp_server_stats_repository.get_stats().await; - - // Merge all the metrics into a single collection - let mut metrics = MetricCollection::default(); - - metrics - .merge(&swarms_stats.metric_collection) - .expect("msg: failed to merge torrent repository metrics"); - metrics - .merge(&tracker_core_stats.metric_collection) - .expect("msg: failed to merge tracker core metrics"); - metrics - .merge(&http_stats.metric_collection) - .expect("msg: failed to merge HTTP core metrics"); - metrics - .merge(&udp_stats_repository.metric_collection) - .expect("failed to merge UDP core metrics"); - metrics - .merge(&udp_server_stats.metric_collection) - .expect("failed to merge UDP server metrics"); - - TrackerLabeledMetrics { metrics } -} - -#[cfg(test)] -mod tests { - use std::sync::Arc; - - use tokio::sync::RwLock; - use tokio_util::sync::CancellationToken; - use torrust_tracker_configuration::Configuration; - use torrust_tracker_core::container::TrackerCoreContainer; - use torrust_tracker_core::{self}; - use torrust_tracker_events::bus::SenderStatus; - use torrust_tracker_http_core::event::bus::EventBus; - use torrust_tracker_http_core::event::sender::Broadcaster; - use torrust_tracker_http_core::statistics::event::listener::run_event_listener; - use torrust_tracker_http_core::statistics::repository::Repository; - use torrust_tracker_swarm_coordination_registry::container::SwarmCoordinationRegistryContainer; - use torrust_tracker_test_helpers::configuration; - use torrust_tracker_udp_core::services::banning::BanService; - - use crate::statistics::metrics::{ProtocolMetrics, TorrentsMetrics}; - use crate::statistics::services::{TrackerMetrics, get_metrics}; - - pub fn tracker_configuration() -> Configuration { - configuration::ephemeral() - } - - #[tokio::test] - async fn the_statistics_service_should_return_the_tracker_metrics() { - let cancellation_token = CancellationToken::new(); - - let config = tracker_configuration(); - let core_config = Arc::new(config.core.clone()); - - let swarm_coordination_registry_container = - Arc::new(SwarmCoordinationRegistryContainer::initialize(SenderStatus::Enabled)); - - let tracker_core_container = - TrackerCoreContainer::initialize_from(&core_config, &swarm_coordination_registry_container.clone()).await; - - let _ban_service = Arc::new(RwLock::new(BanService::new(10))); - - // HTTP core stats - let http_core_broadcaster = Broadcaster::default(); - let http_stats_repository = Arc::new(Repository::new()); - let http_stats_event_bus = Arc::new(EventBus::new( - config.core.tracker_usage_statistics.into(), - http_core_broadcaster.clone(), - )); - - if config.core.tracker_usage_statistics { - let _unused = run_event_listener(http_stats_event_bus.receiver(), cancellation_token, &http_stats_repository); - } - - // UDP server stats - let udp_server_stats_repository = Arc::new(torrust_tracker_udp_server::statistics::repository::Repository::new()); - - let tracker_metrics = get_metrics( - tracker_core_container.in_memory_torrent_repository.clone(), - tracker_core_container.stats_repository.clone(), - http_stats_repository.clone(), - udp_server_stats_repository.clone(), - ) - .await; - - assert_eq!( - tracker_metrics, - TrackerMetrics { - torrents_metrics: TorrentsMetrics::default(), - protocol_metrics: ProtocolMetrics::default(), - } - ); - } -} diff --git a/packages/rest-api-runtime-adapter/Cargo.toml b/packages/rest-api-runtime-adapter/Cargo.toml index 57632846e..4af100498 100644 --- a/packages/rest-api-runtime-adapter/Cargo.toml +++ b/packages/rest-api-runtime-adapter/Cargo.toml @@ -14,6 +14,7 @@ rust-version.workspace = true version.workspace = true [dependencies] +torrust-tracker-configuration = { version = "3.0.0-develop", path = "../configuration" } torrust-tracker-rest-api-application = { version = "3.0.0-develop", path = "../rest-api-application" } torrust-tracker-rest-api-protocol = { version = "3.0.0-develop", path = "../rest-api-protocol" } torrust-tracker-core = { version = "3.0.0-develop", path = "../tracker-core" } @@ -25,3 +26,4 @@ torrust-tracker-swarm-coordination-registry = { version = "3.0.0-develop", path torrust-metrics = "0.1.0" torrust-info-hash = "=0.2.0" async-trait = "0.1" +tokio = { version = "1", features = [ "sync" ] } diff --git a/packages/rest-api-core/src/container.rs b/packages/rest-api-runtime-adapter/src/container.rs similarity index 89% rename from packages/rest-api-core/src/container.rs rename to packages/rest-api-runtime-adapter/src/container.rs index c2e356caa..4afebe35c 100644 --- a/packages/rest-api-core/src/container.rs +++ b/packages/rest-api-runtime-adapter/src/container.rs @@ -1,3 +1,10 @@ +//! Dependency injection container for the REST API server. +//! +//! Wires all tracker internal components (swarm registry, HTTP/UDP cores, etc.) +//! into a single container that the Axum server uses to construct adapters. +//! +//! This was previously in `rest-api-core` and was moved here as part of SI-5 +//! (deprecation of `rest-api-core`). use std::sync::Arc; use tokio::sync::RwLock; @@ -10,6 +17,8 @@ use torrust_tracker_udp_core::services::banning::BanService; use torrust_tracker_udp_core::{self}; use torrust_tracker_udp_server::container::UdpTrackerServerContainer; +/// Container that holds all the internal tracker components needed by the +/// REST API server. pub struct TrackerHttpApiCoreContainer { pub http_api_config: Arc, diff --git a/packages/rest-api-runtime-adapter/src/lib.rs b/packages/rest-api-runtime-adapter/src/lib.rs index 7cde91a69..9d6dc1967 100644 --- a/packages/rest-api-runtime-adapter/src/lib.rs +++ b/packages/rest-api-runtime-adapter/src/lib.rs @@ -15,4 +15,5 @@ //! - Use-case services (those belong to `rest-api-application`). //! - Axum server routing or middleware. pub mod adapters; +pub mod container; pub mod conversion; diff --git a/src/bootstrap/jobs/tracker_apis.rs b/src/bootstrap/jobs/tracker_apis.rs index 1ae267693..6f4dfb358 100644 --- a/src/bootstrap/jobs/tracker_apis.rs +++ b/src/bootstrap/jobs/tracker_apis.rs @@ -30,7 +30,7 @@ use torrust_tracker_axum_rest_api_server::Version; use torrust_tracker_axum_rest_api_server::server::{ApiServer, Launcher}; use torrust_tracker_axum_server::tsl::make_rust_tls; use torrust_tracker_configuration::AccessTokens; -use torrust_tracker_rest_api_core::container::TrackerHttpApiCoreContainer; +use torrust_tracker_rest_api_runtime_adapter::container::TrackerHttpApiCoreContainer; use tracing::instrument; /// This is the message that the "launcher" spawned task sends to the main @@ -104,7 +104,7 @@ mod tests { use torrust_server_lib::registar::Registar; use torrust_tracker_axum_rest_api_server::Version; - use torrust_tracker_rest_api_core::container::TrackerHttpApiCoreContainer; + use torrust_tracker_rest_api_runtime_adapter::container::TrackerHttpApiCoreContainer; use torrust_tracker_test_helpers::configuration::ephemeral_public; use crate::bootstrap::app::initialize_global_services; diff --git a/src/container.rs b/src/container.rs index fcfaafce3..b0167c134 100644 --- a/src/container.rs +++ b/src/container.rs @@ -6,7 +6,7 @@ use torrust_server_lib::registar::Registar; use torrust_tracker_configuration::{Configuration, HttpApi}; use torrust_tracker_core::container::TrackerCoreContainer; use torrust_tracker_http_core::container::{HttpTrackerCoreContainer, HttpTrackerCoreServices}; -use torrust_tracker_rest_api_core::container::TrackerHttpApiCoreContainer; +use torrust_tracker_rest_api_runtime_adapter::container::TrackerHttpApiCoreContainer; use torrust_tracker_swarm_coordination_registry::container::SwarmCoordinationRegistryContainer; use torrust_tracker_udp_core::container::{UdpTrackerCoreContainer, UdpTrackerCoreServices}; use torrust_tracker_udp_core::{self}; From 4270f255e38bd89a9a1cad508536d93ecee3494a Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Mon, 29 Jun 2026 13:32:42 +0100 Subject: [PATCH 3/8] docs(1943): add manual verification evidence for API endpoints --- .../ISSUE.md | 115 +++++++++++++++++- 1 file changed, 109 insertions(+), 6 deletions(-) diff --git a/docs/issues/open/1943-1938-si-5-deprecate-rest-api-core/ISSUE.md b/docs/issues/open/1943-1938-si-5-deprecate-rest-api-core/ISSUE.md index 6f1b0c901..f622be6ca 100644 --- a/docs/issues/open/1943-1938-si-5-deprecate-rest-api-core/ISSUE.md +++ b/docs/issues/open/1943-1938-si-5-deprecate-rest-api-core/ISSUE.md @@ -71,44 +71,146 @@ It has only **one consumer** in the entire workspace: `axum-rest-api-server`. On ## Verification / Progress - [x] No crate in workspace references `torrust-tracker-rest-api-core` -- [ ] Workspace builds cleanly +- [x] Workspace builds cleanly - [ ] Integration tests pass - [x] Pre-commit checks pass - [ ] Pre-push checks pass ## Manual Verification +**✅ All API endpoints working correctly after removing `rest-api-core`.** + Before committing, manually verify the REST API works correctly after removing `rest-api-core`: 1. **Run the tracker locally** with the REST API enabled: ```console - cargo run + cargo run -- --config share/default/config/tracker.development.sqlite3.toml ``` + Tracker started successfully on all ports (UDP 6868/6969, HTTP 7070/7171, API 1212). + 2. **Make test requests**: - Request the stats endpoint: ```console - curl http://localhost:1212/api/v1/stats + curl -s http://localhost:1212/api/v1/stats -H "Authorization: Bearer MyAccessToken" + ``` + + **Initial response** (all zeros): + + ```json + { + "torrents": 0, + "seeders": 0, + "completed": 6, + "leechers": 0, + "tcp4_connections_handled": 0, + "tcp4_announces_handled": 0, + "tcp4_scrapes_handled": 0, + "tcp6_connections_handled": 0, + "tcp6_announces_handled": 0, + "tcp6_scrapes_handled": 0, + "udp_requests_aborted": 0, + "udp_requests_banned": 0, + "udp_banned_ips_total": 0, + "udp_avg_connect_processing_time_ns": 0, + "udp_avg_announce_processing_time_ns": 0, + "udp_avg_scrape_processing_time_ns": 0, + "udp4_requests": 0, + "udp4_connections_handled": 0, + "udp4_announces_handled": 0, + "udp4_scrapes_handled": 0, + "udp4_responses": 0, + "udp4_errors_handled": 0, + "udp6_requests": 0, + "udp6_connections_handled": 0, + "udp6_announces_handled": 0, + "udp6_scrapes_handled": 0, + "udp6_responses": 0, + "udp6_errors_handled": 0 + } ``` - Request the metrics endpoint: ```console - curl http://localhost:1212/api/v1/metrics + curl -s http://localhost:1212/api/v1/metrics -H "Authorization: Bearer MyAccessToken" ``` + **Initial response**: returned all metrics with initial samples (e.g., `tracker_core_persistent_torrents_downloads_total` with `value: 6`). + - Make an announce request using the tracker client: ```console cargo run -p torrust-tracker-client --bin tracker_client -- udp announce udp://localhost:6969/announce 0123456789abcdef0123456789abcdef01234567 ``` + **Announce response**: + + ```json + { + "AnnounceIpv4": { + "transaction_id": -888840697, + "announce_interval": 120, + "leechers": 0, + "seeders": 1, + "peers": [] + } + } + ``` + 3. **Verify stats and metrics changed**: - - Repeat the `/api/v1/stats` request and confirm the values changed (and verify in the tracker console logs that the request was received). + - Repeat the `/api/v1/stats` request: + + ```console + curl -s http://localhost:1212/api/v1/stats -H "Authorization: Bearer MyAccessToken" + ``` + + **Response after announce** (values changed): + + ```json + { + "torrents": 1, + "seeders": 1, + "completed": 6, + "leechers": 0, + "tcp4_connections_handled": 0, + "tcp4_announces_handled": 0, + "tcp4_scrapes_handled": 0, + "tcp6_connections_handled": 0, + "tcp6_announces_handled": 0, + "tcp6_scrapes_handled": 0, + "udp_requests_aborted": 0, + "udp_requests_banned": 0, + "udp_banned_ips_total": 0, + "udp_avg_connect_processing_time_ns": 69019, + "udp_avg_announce_processing_time_ns": 188913, + "udp_avg_scrape_processing_time_ns": 0, + "udp4_requests": 2, + "udp4_connections_handled": 1, + "udp4_announces_handled": 1, + "udp4_scrapes_handled": 0, + "udp4_responses": 2, + "udp4_errors_handled": 0, + "udp6_requests": 0, + "udp6_connections_handled": 0, + "udp6_announces_handled": 0, + "udp6_scrapes_handled": 0, + "udp6_responses": 0, + "udp6_errors_handled": 0 + } + ``` - - Repeat the `/api/v1/metrics` request and confirm the values changed (and verify in the tracker console logs that the request was received). + **Changed values**: torrents `0→1`, seeders `0→1`, `udp4_requests` `0→2`, `udp4_connections_handled` `0→1`, `udp4_announces_handled` `0→1`, `udp4_responses` `0→2`, plus average processing times populated. + + - Repeat the `/api/v1/metrics` request: returned samples with `swarm_coordination_registry_torrents_total: 1.0`, `swarm_coordination_registry_peers_added_total: 1`, `udp_tracker_core_requests_received_total: 2` (1 connect, 1 announce). + + - Tracker console logs confirmed the announce was received: + + ```text + active_peers_total=1 inactive_peers_total=0 active_torrents_total=1 inactive_torrents_total=0 + ``` ### Progress Log @@ -117,3 +219,4 @@ Before committing, manually verify the REST API works correctly after removing ` | 2026-06-24 | Draft spec created | | 2026-06-29 | Implementation confirmed: move `TrackerHttpApiCoreContainer` to `rest-api-runtime-adapter` | | 2026-06-29 | Implementation: container moved, deps removed, directory deleted | +| 2026-06-29 | Manual verification: all API endpoints working correctly (stats, metrics, announce) | From 0c397fa9a55e93b71c7f2c494c65e8b092cfef3d Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Mon, 29 Jun 2026 16:02:38 +0100 Subject: [PATCH 4/8] docs(skills): add use-rest-api skill for REST API usage instructions --- .github/skills/usage/use-rest-api/SKILL.md | 144 ++++++++++++++++++ .../src/v1/middlewares/auth.rs | 1 + .../config/tracker.development.sqlite3.toml | 1 + 3 files changed, 146 insertions(+) create mode 100644 .github/skills/usage/use-rest-api/SKILL.md diff --git a/.github/skills/usage/use-rest-api/SKILL.md b/.github/skills/usage/use-rest-api/SKILL.md new file mode 100644 index 000000000..641b2defb --- /dev/null +++ b/.github/skills/usage/use-rest-api/SKILL.md @@ -0,0 +1,144 @@ +--- +name: use-rest-api +description: Use the Torrust Tracker REST API. Covers authentication, all endpoints (stats, metrics, torrents, auth keys, whitelist), and making announce/scrape requests to verify API behaviour. Triggers on "use API", "test API", "call REST API", "query API", "API endpoint", "curl tracker", "tracker client", "announce request", or "verify API". +metadata: + author: torrust + version: "1.0" +--- + +# Use REST API + +## Prerequisites + +A running tracker with the REST API enabled. The default development config starts the API on port 1212: + +```bash +cargo run +``` + +## Authentication + +All API endpoints (except `/api/health_check`) require an access token. + +### Header Method (preferred) + +```bash +curl -H "Authorization: Bearer MyAccessToken" http://localhost:1212/api/v1/stats +``` + +### Query Parameter Method + +```bash +curl "http://localhost:1212/api/v1/stats?token=MyAccessToken" +``` + +### Configuration + +Tokens are defined in the TOML config file under `[http_api.access_tokens]`: + +```toml +[http_api.access_tokens] +admin = "MyAccessToken" +``` + +Every token in the map has identical permissions — the label (`admin`) is just a human-readable name. + +## Endpoints + +All endpoints use `http://localhost:1212` as base (default dev config). + +### Health Check + +| Method | Endpoint | Auth | +| ------ | ------------------- | ----- | +| GET | `/api/health_check` | ❌ No | + +```bash +curl -s http://localhost:1212/api/health_check +``` + +### Stats + +| Method | Endpoint | Auth | +| ------ | ----------------- | ------ | +| GET | `/api/v1/stats` | ✅ Yes | +| GET | `/api/v1/metrics` | ✅ Yes | + +```bash +curl -s http://localhost:1212/api/v1/stats -H "Authorization: Bearer MyAccessToken" +curl -s http://localhost:1212/api/v1/metrics -H "Authorization: Bearer MyAccessToken" +``` + +### Auth Keys + +| Method | Endpoint | Auth | +| ------ | ------------------------------------ | ------ | +| POST | `/api/v1/key/{seconds_valid_or_key}` | ✅ Yes | +| DELETE | `/api/v1/key/{seconds_valid_or_key}` | ✅ Yes | +| GET | `/api/v1/keys/reload` | ✅ Yes | +| POST | `/api/v1/keys` | ✅ Yes | + +### Whitelist + +| Method | Endpoint | Auth | +| ------ | ------------------------------- | ------ | +| POST | `/api/v1/whitelist/{info_hash}` | ✅ Yes | +| DELETE | `/api/v1/whitelist/{info_hash}` | ✅ Yes | +| GET | `/api/v1/whitelist/reload` | ✅ Yes | + +### Torrents + +| Method | Endpoint | Auth | +| ------ | ----------------------------- | ------ | +| GET | `/api/v1/torrent/{info_hash}` | ✅ Yes | +| GET | `/api/v1/torrents` | ✅ Yes | + +## Making Announce Requests with the Tracker Client + +The `tracker_client` binary can make BitTorrent announce requests to verify the tracker is working. + +### UDP Announce + +```bash +cargo run -p torrust-tracker-client --bin tracker_client -- udp announce udp://localhost:6969/announce 0123456789abcdef0123456789abcdef01234567 +``` + +### HTTP Announce + +```bash +cargo run -p torrust-tracker-client --bin tracker_client -- http announce http://localhost:7070/announce 0123456789abcdef0123456789abcdef01234567 +``` + +### Scrape + +```bash +cargo run -p torrust-tracker-client --bin tracker_client -- udp scrape udp://localhost:6969/announce 0123456789abcdef0123456789abcdef01234567 +``` + +Output defaults to JSON. Use `--format text` for human-readable output. + +## Verification Workflow + +After making an announce request, verify the API reflects the activity: + +1. Check stats changed: + + ```bash + curl -s http://localhost:1212/api/v1/stats -H "Authorization: Bearer MyAccessToken" + ``` + + Expect `torrents` and `seeders` to increase. + +2. Check metrics changed: + + ```bash + curl -s http://localhost:1212/api/v1/metrics -H "Authorization: Bearer MyAccessToken" + ``` + + Expect protocol-specific counters to increase. + +3. Check tracker console logs show the request was received: + + ```text + active_peers_total=1 active_torrents_total=1 + ``` diff --git a/packages/axum-rest-api-server/src/v1/middlewares/auth.rs b/packages/axum-rest-api-server/src/v1/middlewares/auth.rs index 9b5ec2320..b62520335 100644 --- a/packages/axum-rest-api-server/src/v1/middlewares/auth.rs +++ b/packages/axum-rest-api-server/src/v1/middlewares/auth.rs @@ -8,6 +8,7 @@ //! 1. As a `Bearer` token in the `Authorization` header. //! 2. As a `token` GET param in the URL. //! +//! skill-link: use-rest-api //! Using the `Authorization` header: //! //! ```console diff --git a/share/default/config/tracker.development.sqlite3.toml b/share/default/config/tracker.development.sqlite3.toml index d40eba34c..03228aeb3 100644 --- a/share/default/config/tracker.development.sqlite3.toml +++ b/share/default/config/tracker.development.sqlite3.toml @@ -1,4 +1,5 @@ # skill-link: run-tracker-locally +# skill-link: use-rest-api [metadata] app = "torrust-tracker" purpose = "configuration" From 0f878ea7f7cd32b5a76e0bf2048944d87f1df058 Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Mon, 29 Jun 2026 16:25:06 +0100 Subject: [PATCH 5/8] fix(1943): remove stale rest-api-core references from Containerfile --- Containerfile | 3 --- 1 file changed, 3 deletions(-) diff --git a/Containerfile b/Containerfile index 79dc26a7f..0fc624147 100644 --- a/Containerfile +++ b/Containerfile @@ -80,7 +80,6 @@ COPY packages/http-protocol/Cargo.toml packages/http-protocol/ COPY packages/http-core/Cargo.toml packages/http-core/ COPY packages/primitives/Cargo.toml packages/primitives/ COPY packages/rest-api-client/Cargo.toml packages/rest-api-client/ -COPY packages/rest-api-core/Cargo.toml packages/rest-api-core/ COPY packages/rest-api-application/Cargo.toml packages/rest-api-application/ COPY packages/rest-api-protocol/Cargo.toml packages/rest-api-protocol/ COPY packages/rest-api-runtime-adapter/Cargo.toml packages/rest-api-runtime-adapter/ @@ -127,7 +126,6 @@ RUN mkdir -p \ packages/http-core/benches \ packages/primitives/src \ packages/rest-api-client/src \ - packages/rest-api-core/src \ packages/rest-api-application/src \ packages/rest-api-protocol/src \ packages/rest-api-runtime-adapter/src \ @@ -168,7 +166,6 @@ RUN mkdir -p \ packages/http-core/benches/http_tracker_core_benchmark.rs \ packages/primitives/src/lib.rs \ packages/rest-api-client/src/lib.rs \ - packages/rest-api-core/src/lib.rs \ packages/rest-api-application/src/lib.rs \ packages/rest-api-protocol/src/lib.rs \ packages/rest-api-runtime-adapter/src/lib.rs \ From c783e84ce910e9cc967a4f41cc8a7329657cbaee Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Mon, 29 Jun 2026 16:48:14 +0100 Subject: [PATCH 6/8] docs(1943): address Copilot PR review comments - Fix AGENTS.md: change rest-api-runtime-adapter layer from 'client tools' to 'runtime adapter' - Fix packages/AGENTS.md: add Runtime Adapter layer to diagram, update description - Fix ISSUE.md: update status to 'completed', last-updated-utc, check prerequisites and verification - Fix use-rest-api SKILL.md: add Skill Links section --- .github/skills/usage/use-rest-api/SKILL.md | 11 +++++ AGENTS.md | 42 +++++++++---------- .../ISSUE.md | 12 +++--- packages/AGENTS.md | 7 +++- 4 files changed, 43 insertions(+), 29 deletions(-) diff --git a/.github/skills/usage/use-rest-api/SKILL.md b/.github/skills/usage/use-rest-api/SKILL.md index 641b2defb..31170b412 100644 --- a/.github/skills/usage/use-rest-api/SKILL.md +++ b/.github/skills/usage/use-rest-api/SKILL.md @@ -16,6 +16,17 @@ A running tracker with the REST API enabled. The default development config star cargo run ``` +## Skill Links + +This skill depends on these artifacts. If any of them change, review this skill. + +- `share/default/config/tracker.development.sqlite3.toml` +- `packages/axum-rest-api-server/src/v1/middlewares/auth.rs` +- `packages/axum-rest-api-server/src/routes.rs` +- `packages/axum-rest-api-server/src/v1/routes.rs` + +Use the marker `skill-link: use-rest-api` in affected artifacts. + ## Authentication All API endpoints (except `/api/health_check`) require an access token. diff --git a/AGENTS.md b/AGENTS.md index 64fa9e75b..9372c71c4 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -60,27 +60,27 @@ native IPv4/IPv6 support, private/whitelisted mode, and a management REST API. All packages live under `packages/`. The workspace version is `3.0.0-develop`. -| Package | Crate Name | Prefix / Layer | Description | -| --------------------------------- | ------------------------------------------------- | -------------- | --------------------------------------------- | -| `axum-health-check-api-server` | `torrust-tracker-axum-health-check-api-server` | `axum-*` | Health monitoring endpoint | -| `axum-http-server` | `torrust-tracker-axum-http-server` | `axum-*` | BitTorrent HTTP tracker server (BEP 3/23) | -| `axum-rest-api-server` | `torrust-tracker-axum-rest-api-server` | `axum-*` | Management REST API server | -| `axum-server` | `torrust-tracker-axum-server` | `axum-*` | Base Axum HTTP server infrastructure | -| `configuration` | `torrust-tracker-configuration` | domain | Config file parsing, environment variables | -| `events` | `torrust-tracker-events` | domain | Domain event definitions | -| `http-protocol` | `torrust-tracker-http-protocol` | `*-protocol` | HTTP tracker protocol (BEP 3/23) parsing | -| `http-core` | `torrust-tracker-http-core` | `*-core` | HTTP-specific tracker domain logic | -| `primitives` | `torrust-tracker-primitives` | domain | Core domain types (InfoHash, PeerId, ...) | -| `rest-api-client` | `torrust-tracker-rest-api-client` | client tools | REST API client library | -| `rest-api-runtime-adapter` | `torrust-tracker-rest-api-runtime-adapter` | client tools | REST API runtime adapter and container wiring | -| `swarm-coordination-registry` | `torrust-tracker-swarm-coordination-registry` | domain | Torrent/peer coordination registry | -| `test-helpers` | `torrust-tracker-test-helpers` | utilities | Mock servers, test data generation | -| `torrent-repository-benchmarking` | `torrust-tracker-torrent-repository-benchmarking` | benchmarking | Torrent storage benchmarks | -| `tracker-client` | `torrust-tracker-client` | client tools | CLI tracker interaction/testing client | -| `tracker-core` | `torrust-tracker-core` | `*-core` | Central tracker peer-management logic | -| `udp-protocol` | `torrust-tracker-udp-protocol` | `*-protocol` | UDP tracker protocol (BEP 15) framing/parsing | -| `udp-core` | `torrust-tracker-udp-core` | `*-core` | UDP-specific tracker domain logic | -| `udp-server` | `torrust-tracker-udp-server` | server | UDP tracker server implementation | +| Package | Crate Name | Prefix / Layer | Description | +| --------------------------------- | ------------------------------------------------- | --------------- | --------------------------------------------- | +| `axum-health-check-api-server` | `torrust-tracker-axum-health-check-api-server` | `axum-*` | Health monitoring endpoint | +| `axum-http-server` | `torrust-tracker-axum-http-server` | `axum-*` | BitTorrent HTTP tracker server (BEP 3/23) | +| `axum-rest-api-server` | `torrust-tracker-axum-rest-api-server` | `axum-*` | Management REST API server | +| `axum-server` | `torrust-tracker-axum-server` | `axum-*` | Base Axum HTTP server infrastructure | +| `configuration` | `torrust-tracker-configuration` | domain | Config file parsing, environment variables | +| `events` | `torrust-tracker-events` | domain | Domain event definitions | +| `http-protocol` | `torrust-tracker-http-protocol` | `*-protocol` | HTTP tracker protocol (BEP 3/23) parsing | +| `http-core` | `torrust-tracker-http-core` | `*-core` | HTTP-specific tracker domain logic | +| `primitives` | `torrust-tracker-primitives` | domain | Core domain types (InfoHash, PeerId, ...) | +| `rest-api-client` | `torrust-tracker-rest-api-client` | client tools | REST API client library | +| `rest-api-runtime-adapter` | `torrust-tracker-rest-api-runtime-adapter` | runtime adapter | REST API runtime adapter and container wiring | +| `swarm-coordination-registry` | `torrust-tracker-swarm-coordination-registry` | domain | Torrent/peer coordination registry | +| `test-helpers` | `torrust-tracker-test-helpers` | utilities | Mock servers, test data generation | +| `torrent-repository-benchmarking` | `torrust-tracker-torrent-repository-benchmarking` | benchmarking | Torrent storage benchmarks | +| `tracker-client` | `torrust-tracker-client` | client tools | CLI tracker interaction/testing client | +| `tracker-core` | `torrust-tracker-core` | `*-core` | Central tracker peer-management logic | +| `udp-protocol` | `torrust-tracker-udp-protocol` | `*-protocol` | UDP tracker protocol (BEP 15) framing/parsing | +| `udp-core` | `torrust-tracker-udp-core` | `*-core` | UDP-specific tracker domain logic | +| `udp-server` | `torrust-tracker-udp-server` | server | UDP tracker server implementation | **Extracted packages** — previously part of this workspace, now in their own standalone repositories: diff --git a/docs/issues/open/1943-1938-si-5-deprecate-rest-api-core/ISSUE.md b/docs/issues/open/1943-1938-si-5-deprecate-rest-api-core/ISSUE.md index f622be6ca..dc09d63d6 100644 --- a/docs/issues/open/1943-1938-si-5-deprecate-rest-api-core/ISSUE.md +++ b/docs/issues/open/1943-1938-si-5-deprecate-rest-api-core/ISSUE.md @@ -1,12 +1,12 @@ --- doc-type: spec issue-type: task -status: planned +status: completed priority: p2 epic: 1938 github-issue: 1943 spec-path: docs/issues/open/1943-1938-si-5-deprecate-rest-api-core/ISSUE.md -last-updated-utc: 2026-06-24 +last-updated-utc: 2026-06-29 semantic-links: skill-links: - create-issue @@ -39,8 +39,8 @@ It has only **one consumer** in the entire workspace: `axum-rest-api-server`. On ## Prerequisites -- [ ] SI-4 (stats migration) completed — this removes the last consumer of `rest-api-core` types from `axum-rest-api-server`. -- [ ] Verify no other crate in the workspace depends on `rest-api-core`. +- [x] SI-4 (stats migration) completed — this removes the last consumer of `rest-api-core` types from `axum-rest-api-server`. +- [x] Verify no other crate in the workspace depends on `rest-api-core`. ## Scope @@ -72,9 +72,9 @@ It has only **one consumer** in the entire workspace: `axum-rest-api-server`. On - [x] No crate in workspace references `torrust-tracker-rest-api-core` - [x] Workspace builds cleanly -- [ ] Integration tests pass +- [x] Integration tests pass - [x] Pre-commit checks pass -- [ ] Pre-push checks pass +- [x] Pre-push checks pass ## Manual Verification diff --git a/packages/AGENTS.md b/packages/AGENTS.md index ff8209104..a857557da 100644 --- a/packages/AGENTS.md +++ b/packages/AGENTS.md @@ -16,9 +16,12 @@ depend on packages in the same layer or a lower one. │ axum-http-server axum-rest-api-server │ │ axum-health-check-api-server udp-server │ ├────────────────────────────────────────────────────────────────┤ +│ Runtime Adapter │ +│ rest-api-runtime-adapter │ +├────────────────────────────────────────────────────────────────┤ │ Core (domain layer) │ │ http-core udp-core tracker-core │ -│ rest-api-runtime-adapter swarm-coordination-registry │ +│ swarm-coordination-registry │ ├────────────────────────────────────────────────────────────────┤ │ Protocols │ │ http-protocol udp-protocol │ @@ -64,7 +67,7 @@ dependency injection. | `tracker-core` | Central peer management: announce/scrape handlers, auth, whitelist, database abstraction (SQLite/MySQL drivers in `src/databases/driver/`) | | `http-core` | HTTP-specific validation and response formatting | | `udp-core` | UDP connection cookies, crypto, banning logic | -| `rest-api-runtime-adapter` | REST API runtime adapter and container wiring | +| `rest-api-runtime-adapter` | REST API runtime adapter and container wiring (Runtime Adapter layer) | | `swarm-coordination-registry` | Registry of torrents and their peer swarms | ### Protocols (`*-protocol`) From 807e3c7ab1246836c138f507e40c613802083c48 Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Mon, 29 Jun 2026 17:18:54 +0100 Subject: [PATCH 7/8] docs(1943): remove stale rest-api-core references from docs/packages.md --- docs/packages.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/packages.md b/docs/packages.md index bff893621..45cb708dc 100644 --- a/docs/packages.md +++ b/docs/packages.md @@ -32,7 +32,6 @@ packages/ ├── primitives ├── rest-api-application ├── rest-api-client -├── rest-api-core ├── rest-api-protocol ├── rest-api-runtime-adapter ├── swarm-coordination-registry @@ -143,7 +142,7 @@ level, catching violations in pre-commit hooks and CI before merge. | Edge | Description | Current violations | | --------------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------ | -| `core -> server` | Core must not depend on delivery-layer packages | `rest-api-core -> udp-server` | +| `core -> server` | Core must not depend on delivery-layer packages | None (historical `rest-api-core` removed in SI-5) | | `tracker-core -> core` | Tracker core must not depend on its protocol-specific wrappers | None | | `tracker-core -> protocol` | Tracker core must not depend on protocol parsing crates | None | | `tracker-core -> server` | Tracker core must not depend on server crates | None | @@ -236,7 +235,6 @@ See `deny.toml` for the complete configuration. | `rest-api-protocol` | REST API protocol contract | Versioned DTOs, error schemas, auth semantics | | `rest-api-application` | REST API application | Port traits, use-case services, domain-error mapping | | `rest-api-runtime-adapter` | REST API runtime adapter | Tracker-specific port implementations, domain→DTO conversions | -| `rest-api-core` | REST API core (deprecated) | Legacy integration container — to be replaced by application + adapter layers | | **Core Components** | | | | `http-core` | HTTP-specific implementation | Request validation, Response formatting | | `udp-core` | UDP-specific implementation | Connectionless request handling | From 5dda558d9f1ad66ea7e1695c64e0945b9206297d Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Mon, 29 Jun 2026 17:55:53 +0100 Subject: [PATCH 8/8] style(docs/packages.md): align table formatting with trailing pipes --- docs/packages.md | 62 ++++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/docs/packages.md b/docs/packages.md index 45cb708dc..69eb24ef9 100644 --- a/docs/packages.md +++ b/docs/packages.md @@ -224,37 +224,37 @@ See `deny.toml` for the complete configuration. ## Package Catalog -| Package | Description | Key Responsibilities | -| --------------------------------- | ------------------------------------ | ----------------------------------------------------------------------------- | -| **axum-\*** | | | -| `axum-server` | Base Axum HTTP server infrastructure | HTTP server lifecycle management | -| `axum-http-server` | BitTorrent HTTP tracker (BEP 3/23) | Handle announce/scrape requests | -| `axum-rest-api-server` | Management REST API (transport) | HTTP routing, request extraction, response serialization, middleware | -| `axum-health-check-api-server` | Health monitoring endpoint | System health reporting | -| **REST API** | Contract-first layers | See [REST API architecture](#rest-api-contract-first-architecture) | -| `rest-api-protocol` | REST API protocol contract | Versioned DTOs, error schemas, auth semantics | -| `rest-api-application` | REST API application | Port traits, use-case services, domain-error mapping | -| `rest-api-runtime-adapter` | REST API runtime adapter | Tracker-specific port implementations, domain→DTO conversions | -| **Core Components** | | | -| `http-core` | HTTP-specific implementation | Request validation, Response formatting | -| `udp-core` | UDP-specific implementation | Connectionless request handling | -| `tracker-core` | Central tracker logic | Peer management | -| **Protocols** | | | -| `http-protocol` | HTTP tracker protocol (BEP 3/23) | Announce/scrape request parsing | -| `udp-protocol` | UDP tracker protocol (BEP 15) | UDP message framing/parsing | -| **Domain** | | | -| `swarm-coordination-registry` | Peer swarm registry | Torrent/peer coordination | -| `configuration` | Runtime configuration | Config file parsing, Environment variables | -| `primitives` | Domain-specific types | PeerId, Peer, SwarmMetadata | -| `events` | Async event bus | Inter-package communication | -| **Utilities** | | | -| `test-helpers` | Testing utilities | Mock servers, Test data generation | -| **Client Tools** | | | -| `tracker-client` (`packages/`) | Tracker client library | Generic tracker client library | -| `rest-api-client` | API client library | REST API integration | -| **Benchmarking** | | | -| `torrent-repository-benchmarking` | Torrent storage benchmarks | Criterion benchmarks | -| `persistence-benchmark` | Persistence layer benchmarks | SQLite/MySQL/PostgreSQL benchmarks | +| Package | Description | Key Responsibilities | +| --------------------------------- | ------------------------------------ | -------------------------------------------------------------------- | +| **axum-\*** | | | +| `axum-server` | Base Axum HTTP server infrastructure | HTTP server lifecycle management | +| `axum-http-server` | BitTorrent HTTP tracker (BEP 3/23) | Handle announce/scrape requests | +| `axum-rest-api-server` | Management REST API (transport) | HTTP routing, request extraction, response serialization, middleware | +| `axum-health-check-api-server` | Health monitoring endpoint | System health reporting | +| **REST API** | Contract-first layers | See [REST API architecture](#rest-api-contract-first-architecture) | +| `rest-api-protocol` | REST API protocol contract | Versioned DTOs, error schemas, auth semantics | +| `rest-api-application` | REST API application | Port traits, use-case services, domain-error mapping | +| `rest-api-runtime-adapter` | REST API runtime adapter | Tracker-specific port implementations, domain→DTO conversions | +| **Core Components** | | | +| `http-core` | HTTP-specific implementation | Request validation, Response formatting | +| `udp-core` | UDP-specific implementation | Connectionless request handling | +| `tracker-core` | Central tracker logic | Peer management | +| **Protocols** | | | +| `http-protocol` | HTTP tracker protocol (BEP 3/23) | Announce/scrape request parsing | +| `udp-protocol` | UDP tracker protocol (BEP 15) | UDP message framing/parsing | +| **Domain** | | | +| `swarm-coordination-registry` | Peer swarm registry | Torrent/peer coordination | +| `configuration` | Runtime configuration | Config file parsing, Environment variables | +| `primitives` | Domain-specific types | PeerId, Peer, SwarmMetadata | +| `events` | Async event bus | Inter-package communication | +| **Utilities** | | | +| `test-helpers` | Testing utilities | Mock servers, Test data generation | +| **Client Tools** | | | +| `tracker-client` (`packages/`) | Tracker client library | Generic tracker client library | +| `rest-api-client` | API client library | REST API integration | +| **Benchmarking** | | | +| `torrent-repository-benchmarking` | Torrent storage benchmarks | Criterion benchmarks | +| `persistence-benchmark` | Persistence layer benchmarks | SQLite/MySQL/PostgreSQL benchmarks | ### Extracted Packages