mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-26 08:18:18 +00:00
refactor: route admin topology reads through app context (#3774)
* refactor: route admin topology reads through app context * chore: accept app context layer baseline entries
This commit is contained in:
@@ -5,21 +5,22 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
|
||||
## Current Context
|
||||
|
||||
- Issue: [`rustfs/backlog#660`](https://github.com/rustfs/backlog/issues/660)
|
||||
- Branch: `overtrue/arch-admin-runtime-context-resolvers`
|
||||
- Baseline: completed `C-011/C-012/C-013/API-055/API-059/API-079/API-080/API-081/API-082/API-083/API-084/API-085/API-086/API-087/API-088/API-089/API-090/API-091/API-092/API-093/API-094/API-095/API-096/API-097/API-098/API-099/API-100/API-101/API-102/API-103/API-104/API-105/API-106/API-107/API-108/API-109/API-110/API-111/API-112/API-113/API-114/API-115/API-116/API-117/API-118/API-119/API-120/API-121/API-122/API-123/API-124/API-125/API-126/API-127/API-128/API-129/API-130/API-131/API-132/API-133/API-134/API-135/API-136/API-137/API-138/API-139/API-140/API-141/API-142/API-143/API-144/API-145/API-146/API-147/API-148/API-149/API-150/API-151/API-152/API-153/API-154/API-155/API-156/API-157/API-158/API-159`.
|
||||
- Based on: API-159 branch while PR #3772 is pending.
|
||||
- Branch: `overtrue/arch-admin-topology-context-resolvers`
|
||||
- Baseline: completed `C-011/C-012/C-013/API-055/API-059/API-079/API-080/API-081/API-082/API-083/API-084/API-085/API-086/API-087/API-088/API-089/API-090/API-091/API-092/API-093/API-094/API-095/API-096/API-097/API-098/API-099/API-100/API-101/API-102/API-103/API-104/API-105/API-106/API-107/API-108/API-109/API-110/API-111/API-112/API-113/API-114/API-115/API-116/API-117/API-118/API-119/API-120/API-121/API-122/API-123/API-124/API-125/API-126/API-127/API-128/API-129/API-130/API-131/API-132/API-133/API-134/API-135/API-136/API-137/API-138/API-139/API-140/API-141/API-142/API-143/API-144/API-145/API-146/API-147/API-148/API-149/API-150/API-151/API-152/API-153/API-154/API-155/API-156/API-157/API-158/API-159/API-160`.
|
||||
- Based on: API-160 branch while PR #3773 is pending.
|
||||
- PR type for this branch: `consumer-migration`
|
||||
- Runtime behavior changes: none.
|
||||
- Rust code changes: route admin/server action credentials, region, and server
|
||||
config consumers through AppContext resolvers with legacy global fallback.
|
||||
- Rust code changes: route admin topology endpoint, deployment-id, and runtime
|
||||
port consumers through AppContext resolvers with legacy global fallback.
|
||||
- CI/script changes: lock completed owner and test/fuzz boundaries against
|
||||
bare/glob imports, scattered raw ECStore facade subpaths, and startup
|
||||
runtime/root-server/table/S3/app shared/app bucket/app ECStore/admin facade
|
||||
regressions, plus external runtime, test, fuzz, and storage-owner module
|
||||
ECStore compatibility bypasses, plus runtime crate, owner crate, test/fuzz,
|
||||
and storage owner thin bridge regressions, plus app context and notify
|
||||
event-bridge thin module regressions.
|
||||
- Docs changes: record the API-136/API-137/API-138/API-139/API-140/API-141/API-142/API-143/API-144/API-145/API-146/API-147/API-148/API-149/API-150/API-151/API-152/API-153/API-154/API-155/API-156/API-157/API-158/API-159/API-160 owner facade cleanup.
|
||||
event-bridge thin module regressions; accept the reviewed AppContext resolver
|
||||
reverse dependencies in the layer baseline.
|
||||
- Docs changes: record the API-136/API-137/API-138/API-139/API-140/API-141/API-142/API-143/API-144/API-145/API-146/API-147/API-148/API-149/API-150/API-151/API-152/API-153/API-154/API-155/API-156/API-157/API-158/API-159/API-160/API-161 owner facade cleanup.
|
||||
|
||||
## Phase 0 Tasks
|
||||
|
||||
@@ -4312,6 +4313,20 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
|
||||
migration guard, formatting, diff hygiene, Rust risk scan, branch freshness
|
||||
check, pre-commit, and three-expert review.
|
||||
|
||||
- [x] `API-161` Route admin topology reads through AppContext resolvers.
|
||||
- Do: add deployment-id and runtime-port AppContext interfaces, reuse the
|
||||
endpoints resolver, default legacy adapters, and route admin topology
|
||||
consumers through resolvers.
|
||||
- Acceptance: admin site replication, replication handlers, and router code
|
||||
no longer directly read endpoints, deployment id, or runtime port globals
|
||||
outside AppContext default adapters.
|
||||
- Must preserve: site replication endpoint inference, console-port fallback,
|
||||
replication same-target validation, stale same-deployment target detection,
|
||||
and legacy global fallback when AppContext is absent.
|
||||
- Verification: RustFS compile coverage, targeted context resolver tests,
|
||||
migration guard, formatting, diff hygiene, Rust risk scan, branch freshness
|
||||
check, pre-commit, and three-expert review.
|
||||
|
||||
## Next PRs
|
||||
|
||||
1. `consumer-migration`: continue reducing direct global reads behind AppContext resolver boundaries.
|
||||
@@ -4347,11 +4362,33 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
|
||||
| Quality/architecture | pass | API-160 keeps admin runtime action credentials, region, and server config reads behind AppContext resolver boundaries. |
|
||||
| Migration preservation | pass | Admin authorization, object-ZIP token encryption, object-lambda signing, OIDC restart detection, and site replication metadata keep legacy fallback behavior. |
|
||||
| Testing/verification | pass | RustFS focused compile, targeted context tests, formatting, migration guard, diff hygiene, Rust risk scan, and pre-commit passed for API-160. |
|
||||
| Quality/architecture | pass | API-161 keeps admin topology endpoint, deployment id, and runtime port reads behind AppContext resolver boundaries. |
|
||||
| Migration preservation | pass | Site replication endpoint inference, same-target checks, same-deployment stale target detection, and runtime-port fallback keep legacy behavior. |
|
||||
| Testing/verification | pass | RustFS focused compile, targeted context tests, formatting, migration guard, diff hygiene, Rust risk scan, and pre-commit passed for API-161. |
|
||||
| Testing/verification | pass | CI follow-up: layer dependency baseline accepts the reviewed AppContext resolver reverse dependencies, and the layer guard passes. |
|
||||
|
||||
## Verification Notes
|
||||
|
||||
Passed before push:
|
||||
|
||||
- Issue #660 API-161 current slice:
|
||||
- `cargo check --tests -p rustfs`: passed.
|
||||
- `cargo test -p rustfs resolver_helpers_are_context_first_and_fallback_when_context_is_absent --lib`:
|
||||
passed.
|
||||
- `cargo fmt --all`: passed.
|
||||
- `cargo fmt --all --check`: passed.
|
||||
- `git diff --check`: passed.
|
||||
- `bash -n scripts/check_architecture_migration_rules.sh`: passed.
|
||||
- `./scripts/check_architecture_migration_rules.sh`: passed.
|
||||
- `./scripts/check_layer_dependencies.sh`: passed after CI baseline
|
||||
follow-up.
|
||||
- `make pre-commit`: passed.
|
||||
- AppContext admin topology resolver scan: passed; direct admin deployment
|
||||
id, endpoint, and runtime port global reads are isolated to AppContext
|
||||
default adapters.
|
||||
- Rust risk scan: no new production panic/todo/unsafe/cast risks added; new
|
||||
unwrap/expect hits are resolver fallback plumbing or test assertions.
|
||||
|
||||
- Issue #660 API-160 current slice:
|
||||
- `cargo check --tests -p rustfs`: passed.
|
||||
- `cargo test -p rustfs resolver_helpers_are_context_first_and_fallback_when_context_is_absent --lib`:
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
use super::super::StorageError;
|
||||
use super::super::bucket_target_sys::{BucketTargetError, BucketTargetSys};
|
||||
use super::super::global_rustfs_port;
|
||||
use super::super::metadata::BUCKET_TARGETS_FILE;
|
||||
use super::super::metadata_sys;
|
||||
use super::super::metadata_sys::get_replication_config;
|
||||
@@ -25,7 +24,7 @@ use crate::admin::auth::validate_admin_request;
|
||||
use crate::admin::handlers::site_replication::site_replication_peer_deployment_id_for_endpoint;
|
||||
use crate::admin::router::{AdminOperation, Operation, S3Router};
|
||||
use crate::admin::utils::read_compatible_admin_body;
|
||||
use crate::app::context::resolve_object_store_handle;
|
||||
use crate::app::context::{resolve_object_store_handle, resolve_runtime_port};
|
||||
use crate::auth::{check_key_valid, get_session_token};
|
||||
use crate::error::ApiError;
|
||||
use crate::server::{ADMIN_PREFIX, RemoteAddr};
|
||||
@@ -223,7 +222,7 @@ impl Operation for SetRemoteTargetHandler {
|
||||
let same_target = rustfs_utils::net::is_local_host(
|
||||
target_url.host().unwrap_or(Host::Domain("localhost")),
|
||||
target_url.port().unwrap_or(80),
|
||||
global_rustfs_port(),
|
||||
resolve_runtime_port(),
|
||||
)
|
||||
.unwrap_or_default();
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ use super::super::replication::{ResyncOpts, get_global_replication_pool};
|
||||
use super::super::target::{ARN, BucketTarget, BucketTargetType, BucketTargets, Credentials};
|
||||
use super::super::{AdminReplicationConfigExt as _, AdminVersioningConfigExt as _};
|
||||
use super::super::{delete_admin_config, read_admin_config, save_admin_config};
|
||||
use super::super::{get_global_deployment_id, get_global_endpoints_opt, global_rustfs_port};
|
||||
use crate::admin::auth::validate_admin_request;
|
||||
use crate::admin::router::{AdminOperation, Operation, S3Router};
|
||||
use crate::admin::site_replication_identity::{
|
||||
@@ -33,7 +32,10 @@ use crate::admin::site_replication_identity::{
|
||||
site_identity_key,
|
||||
};
|
||||
use crate::admin::utils::{encode_compatible_admin_payload, read_compatible_admin_body};
|
||||
use crate::app::context::{resolve_object_store_handle, resolve_region, resolve_server_config};
|
||||
use crate::app::context::{
|
||||
resolve_deployment_id, resolve_endpoints_handle, resolve_object_store_handle, resolve_region, resolve_runtime_port,
|
||||
resolve_server_config,
|
||||
};
|
||||
use crate::auth::{check_key_valid, get_session_token};
|
||||
use crate::config::get_config_snapshot;
|
||||
use crate::error::ApiError;
|
||||
@@ -671,7 +673,7 @@ fn runtime_tls_enabled_with(endpoints: Option<&super::super::EndpointServerPools
|
||||
}
|
||||
|
||||
fn runtime_tls_enabled() -> bool {
|
||||
let endpoints = get_global_endpoints_opt();
|
||||
let endpoints = resolve_endpoints_handle();
|
||||
runtime_tls_enabled_with(endpoints.as_ref())
|
||||
}
|
||||
|
||||
@@ -822,7 +824,7 @@ fn request_endpoint(uri: &Uri, headers: &HeaderMap) -> String {
|
||||
.map(str::to_string)
|
||||
.or_else(|| uri.authority().map(|value| value.as_str().to_string()))
|
||||
.or_else(|| {
|
||||
get_global_endpoints_opt().and_then(|endpoints| {
|
||||
resolve_endpoints_handle().and_then(|endpoints| {
|
||||
endpoints
|
||||
.as_ref()
|
||||
.iter()
|
||||
@@ -831,7 +833,7 @@ fn request_endpoint(uri: &Uri, headers: &HeaderMap) -> String {
|
||||
.map(|endpoint| endpoint.host_port())
|
||||
})
|
||||
})
|
||||
.unwrap_or_else(|| format!("127.0.0.1:{}", global_rustfs_port()));
|
||||
.unwrap_or_else(|| format!("127.0.0.1:{}", resolve_runtime_port()));
|
||||
|
||||
format!("{scheme}://{host}")
|
||||
}
|
||||
@@ -859,7 +861,7 @@ fn site_replication_local_endpoint(uri: &Uri, headers: &HeaderMap) -> String {
|
||||
if !matches!(parsed.scheme(), "http" | "https") || parsed.host_str().is_none() {
|
||||
return request_endpoint(&Uri::from_static("/"), &HeaderMap::new());
|
||||
}
|
||||
if parsed.port_or_known_default() == runtime_console_port() && parsed.set_port(Some(global_rustfs_port())).is_ok() {
|
||||
if parsed.port_or_known_default() == runtime_console_port() && parsed.set_port(Some(resolve_runtime_port())).is_ok() {
|
||||
parsed.to_string().trim_end_matches('/').to_string()
|
||||
} else {
|
||||
endpoint
|
||||
@@ -899,7 +901,7 @@ fn non_negative_u64(value: i64) -> u64 {
|
||||
|
||||
fn current_local_peer(req: &S3Request<Body>, state: &SiteReplicationState) -> PeerInfo {
|
||||
let endpoint = site_replication_local_endpoint(&req.uri, &req.headers);
|
||||
let deployment_id = get_global_deployment_id().unwrap_or_else(|| deployment_id_for_endpoint(&endpoint));
|
||||
let deployment_id = resolve_deployment_id().unwrap_or_else(|| deployment_id_for_endpoint(&endpoint));
|
||||
let stored_peer = state.peers.get(&deployment_id);
|
||||
|
||||
PeerInfo {
|
||||
@@ -923,7 +925,7 @@ fn current_local_peer(req: &S3Request<Body>, state: &SiteReplicationState) -> Pe
|
||||
|
||||
fn current_local_runtime_peer(state: &SiteReplicationState) -> PeerInfo {
|
||||
let endpoint = current_local_runtime_endpoint();
|
||||
let deployment_id = get_global_deployment_id().unwrap_or_else(|| deployment_id_for_endpoint(&endpoint));
|
||||
let deployment_id = resolve_deployment_id().unwrap_or_else(|| deployment_id_for_endpoint(&endpoint));
|
||||
let stored_peer = state.peers.get(&deployment_id);
|
||||
|
||||
PeerInfo {
|
||||
@@ -4287,7 +4289,7 @@ impl Operation for SiteReplicationEditHandler {
|
||||
};
|
||||
|
||||
for target in current_state.peers.values() {
|
||||
let local_target = get_global_deployment_id()
|
||||
let local_target = resolve_deployment_id()
|
||||
.as_ref()
|
||||
.is_some_and(|deployment_id| deployment_id == &target.deployment_id);
|
||||
if local_target {
|
||||
|
||||
+1
-15
@@ -136,9 +136,7 @@ mod ecstore_error {
|
||||
}
|
||||
|
||||
mod ecstore_global {
|
||||
pub(crate) use crate::storage::ecstore_global::{
|
||||
GLOBAL_BOOT_TIME, get_global_bucket_monitor, get_global_deployment_id, get_global_endpoints_opt, global_rustfs_port,
|
||||
};
|
||||
pub(crate) use crate::storage::ecstore_global::{GLOBAL_BOOT_TIME, get_global_bucket_monitor};
|
||||
}
|
||||
|
||||
#[allow(unused_imports)]
|
||||
@@ -516,18 +514,6 @@ pub(crate) fn get_global_bucket_monitor() -> Option<Arc<bandwidth::monitor::Moni
|
||||
ecstore_global::get_global_bucket_monitor()
|
||||
}
|
||||
|
||||
pub(crate) fn get_global_deployment_id() -> Option<String> {
|
||||
ecstore_global::get_global_deployment_id()
|
||||
}
|
||||
|
||||
pub(crate) fn get_global_endpoints_opt() -> Option<EndpointServerPools> {
|
||||
ecstore_global::get_global_endpoints_opt()
|
||||
}
|
||||
|
||||
pub(crate) fn global_rustfs_port() -> u16 {
|
||||
ecstore_global::global_rustfs_port()
|
||||
}
|
||||
|
||||
pub(crate) async fn collect_local_metrics(
|
||||
types: MetricType,
|
||||
opts: &CollectMetricsOpts,
|
||||
|
||||
@@ -16,6 +16,7 @@ use super::GLOBAL_BOOT_TIME;
|
||||
use super::PeerRestClient;
|
||||
use super::bandwidth::monitor::BandwidthDetails;
|
||||
use super::bucket_target_sys::{BucketTargetSys, PutObjectOptions, RemoveObjectOptions, S3ClientError, TargetClient};
|
||||
use super::get_global_bucket_monitor;
|
||||
use super::get_global_notification_sys;
|
||||
use super::metadata::BUCKET_TARGETS_FILE;
|
||||
use super::metadata_sys;
|
||||
@@ -26,10 +27,9 @@ use super::replication::{
|
||||
use super::target::{BucketTarget, BucketTargetType, BucketTargets};
|
||||
use super::versioning_sys::BucketVersioningSys;
|
||||
use super::{AdminReplicationConfigExt as _, AdminVersioningConfigExt as _};
|
||||
use super::{get_global_bucket_monitor, get_global_deployment_id};
|
||||
use crate::admin::console::{is_console_path, make_console_server};
|
||||
use crate::admin::handlers::oidc::is_oidc_path;
|
||||
use crate::app::context::{resolve_object_store_handle, resolve_region, resolve_server_config};
|
||||
use crate::app::context::{resolve_deployment_id, resolve_object_store_handle, resolve_region, resolve_server_config};
|
||||
use crate::app::object_usecase::DefaultObjectUsecase;
|
||||
use crate::auth::{check_key_valid, get_session_token};
|
||||
use crate::error::ApiError;
|
||||
@@ -1829,7 +1829,7 @@ async fn check_replication_target(bucket: &str, target: &BucketTarget) -> Replic
|
||||
|
||||
if target.target_bucket == bucket
|
||||
&& !target.deployment_id.is_empty()
|
||||
&& get_global_deployment_id().as_deref() == Some(target.deployment_id.as_str())
|
||||
&& resolve_deployment_id().as_deref() == Some(target.deployment_id.as_str())
|
||||
{
|
||||
result.status = "FAILED".to_string();
|
||||
result.error = Some("target bucket must not match source bucket on the same deployment".to_string());
|
||||
|
||||
@@ -84,6 +84,16 @@ pub fn resolve_endpoints_handle() -> Option<EndpointServerPools> {
|
||||
resolve_endpoints_handle_with(get_global_app_context(), || default_endpoints_interface().handle())
|
||||
}
|
||||
|
||||
/// Resolve deployment identity using AppContext-first precedence.
|
||||
pub fn resolve_deployment_id() -> Option<String> {
|
||||
resolve_deployment_id_with(get_global_app_context(), || default_deployment_id_interface().get())
|
||||
}
|
||||
|
||||
/// Resolve runtime port using AppContext-first precedence.
|
||||
pub fn resolve_runtime_port() -> u16 {
|
||||
resolve_runtime_port_with(get_global_app_context(), || default_runtime_port_interface().get())
|
||||
}
|
||||
|
||||
/// Resolve lock client using AppContext-first precedence.
|
||||
pub fn resolve_lock_client() -> Option<Arc<dyn LockClient>> {
|
||||
resolve_lock_client_with(get_global_app_context(), || default_lock_client_interface().handle())
|
||||
@@ -163,6 +173,14 @@ fn resolve_endpoints_handle_with(
|
||||
context.and_then(|context| context.endpoints().handle()).or_else(fallback)
|
||||
}
|
||||
|
||||
fn resolve_deployment_id_with(context: Option<Arc<AppContext>>, fallback: impl FnOnce() -> Option<String>) -> Option<String> {
|
||||
context.and_then(|context| context.deployment_id().get()).or_else(fallback)
|
||||
}
|
||||
|
||||
fn resolve_runtime_port_with(context: Option<Arc<AppContext>>, fallback: impl FnOnce() -> u16) -> u16 {
|
||||
context.map_or_else(fallback, |context| context.runtime_port().get())
|
||||
}
|
||||
|
||||
fn resolve_lock_client_with(
|
||||
context: Option<Arc<AppContext>>,
|
||||
fallback: impl FnOnce() -> Option<Arc<dyn LockClient>>,
|
||||
@@ -226,9 +244,9 @@ mod tests {
|
||||
use crate::app::context::global::AppContextTestInterfaces;
|
||||
use crate::app::context::handles::default_notify_interface;
|
||||
use crate::app::context::interfaces::{
|
||||
ActionCredentialInterface, BucketMetadataInterface, BufferConfigInterface, EndpointsInterface, IamInterface,
|
||||
KmsInterface, KmsRuntimeInterface, LocalNodeNameInterface, LockClientInterface, RegionInterface, ServerConfigInterface,
|
||||
TierConfigInterface,
|
||||
ActionCredentialInterface, BucketMetadataInterface, BufferConfigInterface, DeploymentIdInterface, EndpointsInterface,
|
||||
IamInterface, KmsInterface, KmsRuntimeInterface, LocalNodeNameInterface, LockClientInterface, RegionInterface,
|
||||
RuntimePortInterface, ServerConfigInterface, TierConfigInterface,
|
||||
};
|
||||
use crate::config::{RustFSBufferConfig, WorkloadProfile};
|
||||
use async_trait::async_trait;
|
||||
@@ -292,6 +310,26 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
struct TestDeploymentIdInterface {
|
||||
id: Option<String>,
|
||||
}
|
||||
|
||||
impl DeploymentIdInterface for TestDeploymentIdInterface {
|
||||
fn get(&self) -> Option<String> {
|
||||
self.id.clone()
|
||||
}
|
||||
}
|
||||
|
||||
struct TestRuntimePortInterface {
|
||||
port: u16,
|
||||
}
|
||||
|
||||
impl RuntimePortInterface for TestRuntimePortInterface {
|
||||
fn get(&self) -> u16 {
|
||||
self.port
|
||||
}
|
||||
}
|
||||
|
||||
struct TestLockClientInterface {
|
||||
client: Option<Arc<dyn LockClient>>,
|
||||
}
|
||||
@@ -426,6 +464,10 @@ mod tests {
|
||||
let fallback_lock_client: Arc<dyn LockClient> = Arc::new(LocalClient::new());
|
||||
let context_node_name = "context-node".to_string();
|
||||
let fallback_node_name = "fallback-node".to_string();
|
||||
let context_deployment_id = "context-deployment".to_string();
|
||||
let fallback_deployment_id = "fallback-deployment".to_string();
|
||||
let context_runtime_port = 19000;
|
||||
let fallback_runtime_port = 29000;
|
||||
let context_credentials = Credentials {
|
||||
access_key: "context-access-key".to_string(),
|
||||
..Default::default()
|
||||
@@ -454,6 +496,12 @@ mod tests {
|
||||
endpoints: Arc::new(TestEndpointsInterface {
|
||||
endpoints: Some(endpoints.clone()),
|
||||
}),
|
||||
deployment_id: Arc::new(TestDeploymentIdInterface {
|
||||
id: Some(context_deployment_id.clone()),
|
||||
}),
|
||||
runtime_port: Arc::new(TestRuntimePortInterface {
|
||||
port: context_runtime_port,
|
||||
}),
|
||||
lock_client: Arc::new(TestLockClientInterface {
|
||||
client: Some(context_lock_client.clone()),
|
||||
}),
|
||||
@@ -497,6 +545,15 @@ mod tests {
|
||||
.drives_per_set,
|
||||
endpoints.as_ref()[0].drives_per_set
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_deployment_id_with(Some(context.clone()), || Some(fallback_deployment_id.clone()))
|
||||
.expect("context deployment id"),
|
||||
context_deployment_id
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_runtime_port_with(Some(context.clone()), || fallback_runtime_port),
|
||||
context_runtime_port
|
||||
);
|
||||
assert!(Arc::ptr_eq(
|
||||
&resolve_lock_client_with(Some(context.clone()), || None).expect("context lock client"),
|
||||
&context_lock_client
|
||||
@@ -549,6 +606,11 @@ mod tests {
|
||||
.drives_per_set,
|
||||
endpoints.as_ref()[0].drives_per_set
|
||||
);
|
||||
assert_eq!(
|
||||
resolve_deployment_id_with(None, || Some(fallback_deployment_id.clone())).expect("fallback deployment id"),
|
||||
fallback_deployment_id
|
||||
);
|
||||
assert_eq!(resolve_runtime_port_with(None, || fallback_runtime_port), fallback_runtime_port);
|
||||
assert!(Arc::ptr_eq(
|
||||
&resolve_lock_client_with(None, || Some(fallback_lock_client.clone())).expect("fallback lock client"),
|
||||
&fallback_lock_client
|
||||
|
||||
@@ -15,14 +15,14 @@
|
||||
use super::super::{ECStore, set_object_store_resolver};
|
||||
use super::handles::{
|
||||
IamHandle, KmsHandle, default_action_credential_interface, default_bucket_metadata_interface,
|
||||
default_buffer_config_interface, default_endpoints_interface, default_kms_runtime_interface,
|
||||
default_buffer_config_interface, default_deployment_id_interface, default_endpoints_interface, default_kms_runtime_interface,
|
||||
default_local_node_name_interface, default_lock_client_interface, default_notify_interface, default_region_interface,
|
||||
default_server_config_interface, default_tier_config_interface,
|
||||
default_runtime_port_interface, default_server_config_interface, default_tier_config_interface,
|
||||
};
|
||||
use super::interfaces::{
|
||||
ActionCredentialInterface, BucketMetadataInterface, BufferConfigInterface, EndpointsInterface, IamInterface, KmsInterface,
|
||||
KmsRuntimeInterface, LocalNodeNameInterface, LockClientInterface, NotifyInterface, RegionInterface, ServerConfigInterface,
|
||||
TierConfigInterface,
|
||||
ActionCredentialInterface, BucketMetadataInterface, BufferConfigInterface, DeploymentIdInterface, EndpointsInterface,
|
||||
IamInterface, KmsInterface, KmsRuntimeInterface, LocalNodeNameInterface, LockClientInterface, NotifyInterface,
|
||||
RegionInterface, RuntimePortInterface, ServerConfigInterface, TierConfigInterface,
|
||||
};
|
||||
use rustfs_iam::{store::object::ObjectStore, sys::IamSys};
|
||||
use rustfs_kms::KmsServiceManager;
|
||||
@@ -39,6 +39,8 @@ pub struct AppContext {
|
||||
notify: Arc<dyn NotifyInterface>,
|
||||
bucket_metadata: Arc<dyn BucketMetadataInterface>,
|
||||
endpoints: Arc<dyn EndpointsInterface>,
|
||||
deployment_id: Arc<dyn DeploymentIdInterface>,
|
||||
runtime_port: Arc<dyn RuntimePortInterface>,
|
||||
lock_client: Arc<dyn LockClientInterface>,
|
||||
local_node_name: Arc<dyn LocalNodeNameInterface>,
|
||||
action_credentials: Arc<dyn ActionCredentialInterface>,
|
||||
@@ -58,6 +60,8 @@ impl AppContext {
|
||||
notify: default_notify_interface(),
|
||||
bucket_metadata: default_bucket_metadata_interface(),
|
||||
endpoints: default_endpoints_interface(),
|
||||
deployment_id: default_deployment_id_interface(),
|
||||
runtime_port: default_runtime_port_interface(),
|
||||
lock_client: default_lock_client_interface(),
|
||||
local_node_name: default_local_node_name_interface(),
|
||||
action_credentials: default_action_credential_interface(),
|
||||
@@ -105,6 +109,14 @@ impl AppContext {
|
||||
self.endpoints.clone()
|
||||
}
|
||||
|
||||
pub fn deployment_id(&self) -> Arc<dyn DeploymentIdInterface> {
|
||||
self.deployment_id.clone()
|
||||
}
|
||||
|
||||
pub fn runtime_port(&self) -> Arc<dyn RuntimePortInterface> {
|
||||
self.runtime_port.clone()
|
||||
}
|
||||
|
||||
pub fn lock_client(&self) -> Arc<dyn LockClientInterface> {
|
||||
self.lock_client.clone()
|
||||
}
|
||||
@@ -142,6 +154,8 @@ pub(super) struct AppContextTestInterfaces {
|
||||
pub(super) notify: Arc<dyn NotifyInterface>,
|
||||
pub(super) bucket_metadata: Arc<dyn BucketMetadataInterface>,
|
||||
pub(super) endpoints: Arc<dyn EndpointsInterface>,
|
||||
pub(super) deployment_id: Arc<dyn DeploymentIdInterface>,
|
||||
pub(super) runtime_port: Arc<dyn RuntimePortInterface>,
|
||||
pub(super) lock_client: Arc<dyn LockClientInterface>,
|
||||
pub(super) local_node_name: Arc<dyn LocalNodeNameInterface>,
|
||||
pub(super) action_credentials: Arc<dyn ActionCredentialInterface>,
|
||||
@@ -162,6 +176,8 @@ impl AppContext {
|
||||
notify: interfaces.notify,
|
||||
bucket_metadata: interfaces.bucket_metadata,
|
||||
endpoints: interfaces.endpoints,
|
||||
deployment_id: interfaces.deployment_id,
|
||||
runtime_port: interfaces.runtime_port,
|
||||
lock_client: interfaces.lock_client,
|
||||
local_node_name: interfaces.local_node_name,
|
||||
action_credentials: interfaces.action_credentials,
|
||||
|
||||
@@ -15,11 +15,14 @@
|
||||
use super::super::EndpointServerPools;
|
||||
use super::super::TierConfigMgr;
|
||||
use super::super::metadata_sys::{BucketMetadataSys, get_global_bucket_metadata_sys};
|
||||
use super::super::{get_global_endpoints_opt, get_global_lock_client, get_global_region, get_global_tier_config_mgr};
|
||||
use super::super::{
|
||||
get_global_deployment_id, get_global_endpoints_opt, get_global_lock_client, get_global_region, get_global_tier_config_mgr,
|
||||
global_rustfs_port,
|
||||
};
|
||||
use super::interfaces::{
|
||||
ActionCredentialInterface, BucketMetadataInterface, BufferConfigInterface, EndpointsInterface, IamInterface, KmsInterface,
|
||||
KmsRuntimeInterface, LocalNodeNameInterface, LockClientInterface, NotifyInterface, RegionInterface, ServerConfigInterface,
|
||||
TierConfigInterface,
|
||||
ActionCredentialInterface, BucketMetadataInterface, BufferConfigInterface, DeploymentIdInterface, EndpointsInterface,
|
||||
IamInterface, KmsInterface, KmsRuntimeInterface, LocalNodeNameInterface, LockClientInterface, NotifyInterface,
|
||||
RegionInterface, RuntimePortInterface, ServerConfigInterface, TierConfigInterface,
|
||||
};
|
||||
use crate::config::{RustFSBufferConfig, get_global_buffer_config};
|
||||
use async_trait::async_trait;
|
||||
@@ -129,6 +132,26 @@ impl EndpointsInterface for EndpointsHandle {
|
||||
}
|
||||
}
|
||||
|
||||
/// Default deployment identity interface adapter.
|
||||
#[derive(Default)]
|
||||
pub struct DeploymentIdHandle;
|
||||
|
||||
impl DeploymentIdInterface for DeploymentIdHandle {
|
||||
fn get(&self) -> Option<String> {
|
||||
get_global_deployment_id()
|
||||
}
|
||||
}
|
||||
|
||||
/// Default runtime port interface adapter.
|
||||
#[derive(Default)]
|
||||
pub struct RuntimePortHandle;
|
||||
|
||||
impl RuntimePortInterface for RuntimePortHandle {
|
||||
fn get(&self) -> u16 {
|
||||
global_rustfs_port()
|
||||
}
|
||||
}
|
||||
|
||||
/// Default lock client interface adapter.
|
||||
#[derive(Default)]
|
||||
pub struct LockClientHandle;
|
||||
@@ -216,6 +239,14 @@ pub fn default_endpoints_interface() -> Arc<dyn EndpointsInterface> {
|
||||
Arc::new(EndpointsHandle)
|
||||
}
|
||||
|
||||
pub fn default_deployment_id_interface() -> Arc<dyn DeploymentIdInterface> {
|
||||
Arc::new(DeploymentIdHandle)
|
||||
}
|
||||
|
||||
pub fn default_runtime_port_interface() -> Arc<dyn RuntimePortInterface> {
|
||||
Arc::new(RuntimePortHandle)
|
||||
}
|
||||
|
||||
pub fn default_lock_client_interface() -> Arc<dyn LockClientInterface> {
|
||||
Arc::new(LockClientHandle)
|
||||
}
|
||||
|
||||
@@ -70,6 +70,16 @@ pub trait EndpointsInterface: Send + Sync {
|
||||
fn handle(&self) -> Option<EndpointServerPools>;
|
||||
}
|
||||
|
||||
/// Deployment identity interface for admin topology integration.
|
||||
pub trait DeploymentIdInterface: Send + Sync {
|
||||
fn get(&self) -> Option<String>;
|
||||
}
|
||||
|
||||
/// Runtime port interface for admin topology integration.
|
||||
pub trait RuntimePortInterface: Send + Sync {
|
||||
fn get(&self) -> u16;
|
||||
}
|
||||
|
||||
/// Lock client interface for application-layer use-cases.
|
||||
pub trait LockClientInterface: Send + Sync {
|
||||
fn handle(&self) -> Option<Arc<dyn LockClient>>;
|
||||
|
||||
@@ -630,6 +630,10 @@ pub(crate) fn get_global_endpoints_opt() -> Option<EndpointServerPools> {
|
||||
crate::storage::get_global_endpoints_opt()
|
||||
}
|
||||
|
||||
pub(crate) fn get_global_deployment_id() -> Option<String> {
|
||||
crate::storage::get_global_deployment_id()
|
||||
}
|
||||
|
||||
pub(crate) fn get_global_lock_client() -> Option<Arc<dyn rustfs_lock::client::LockClient>> {
|
||||
crate::storage::get_global_lock_client()
|
||||
}
|
||||
@@ -638,6 +642,10 @@ pub(crate) fn get_global_region() -> Option<s3s::region::Region> {
|
||||
crate::storage::get_global_region()
|
||||
}
|
||||
|
||||
pub(crate) fn global_rustfs_port() -> u16 {
|
||||
crate::storage::global_rustfs_port()
|
||||
}
|
||||
|
||||
pub(crate) fn get_global_tier_config_mgr() -> Arc<tokio::sync::RwLock<TierConfigMgr>> {
|
||||
crate::storage::get_global_tier_config_mgr()
|
||||
}
|
||||
|
||||
@@ -813,10 +813,18 @@ pub(crate) fn get_global_endpoints_opt() -> Option<EndpointServerPools> {
|
||||
ecstore_global::get_global_endpoints_opt()
|
||||
}
|
||||
|
||||
pub(crate) fn get_global_deployment_id() -> Option<String> {
|
||||
ecstore_global::get_global_deployment_id()
|
||||
}
|
||||
|
||||
pub(crate) fn get_global_region() -> Option<s3s::region::Region> {
|
||||
ecstore_global::get_global_region()
|
||||
}
|
||||
|
||||
pub(crate) fn global_rustfs_port() -> u16 {
|
||||
ecstore_global::global_rustfs_port()
|
||||
}
|
||||
|
||||
pub(crate) fn get_global_tier_config_mgr() -> Arc<tokio::sync::RwLock<TierConfigMgr>> {
|
||||
ecstore_global::get_global_tier_config_mgr()
|
||||
}
|
||||
|
||||
@@ -41,15 +41,22 @@ accepted|rustfs/src/protocols/client.rs|infra->interface|crate::storage::ecfs::F
|
||||
accepted|rustfs/src/server/audit.rs|infra->app|crate::app::context::resolve_server_config|config resolution uses global AppContext
|
||||
accepted|rustfs/src/server/event.rs|infra->app|crate::app::context::resolve_server_config|config resolution uses global AppContext
|
||||
accepted|rustfs/src/server/http.rs|infra->interface|crate::admin|HTTP server routes to admin handlers
|
||||
accepted|rustfs/src/server/layer.rs|infra->app|crate::app::context::resolve_kms_runtime_service_manager|HTTP layer reads KMS runtime through AppContext resolver
|
||||
accepted|rustfs/src/server/layer.rs|infra->interface|crate::admin::console::is_console_path|pure path predicate for routing
|
||||
accepted|rustfs/src/server/layer.rs|infra->interface|crate::admin::handlers::health::HealthProbe|HTTP layer builds health responses
|
||||
accepted|rustfs/src/server/layer.rs|infra->interface|crate::admin::handlers::health::build_health_response_parts|HTTP layer builds health responses
|
||||
accepted|rustfs/src/server/readiness.rs|infra->app|crate::app::context::resolve_endpoints_handle|readiness checks endpoint availability through AppContext resolver
|
||||
accepted|rustfs/src/server/readiness.rs|infra->app|crate::app::context::resolve_iam_ready|readiness checks IAM availability through AppContext resolver
|
||||
accepted|rustfs/src/startup_iam.rs|infra->app|crate::app::context::AppContext|startup wires IAM bootstrap through AppContext
|
||||
accepted|rustfs/src/storage/ecfs_extend.rs|infra->app|crate::app::context::resolve_buffer_config|storage buffer sizing reads runtime config through AppContext resolver
|
||||
accepted|rustfs/src/storage/ecfs_extend.rs|infra->interface|crate::storage::ecfs::ListObjectUnorderedQuery|storage extension uses current ECFS interface query type
|
||||
accepted|rustfs/src/storage/ecfs_test.rs|infra->interface|crate::storage::ecfs::FS|storage tests exercise current ECFS interface path
|
||||
accepted|rustfs/src/storage/ecfs_test.rs|infra->interface|crate::storage::ecfs::validate_object_lock_configuration_input|storage tests exercise current ECFS object-lock validator
|
||||
accepted|rustfs/src/storage/ecfs_test.rs|infra->interface|crate::storage::s3_api::common::rustfs_initiator|storage tests use current S3 API initiator helper
|
||||
accepted|rustfs/src/storage/ecfs_test.rs|infra->interface|crate::storage::s3_api::common::rustfs_owner|storage tests use current S3 API owner helper
|
||||
accepted|rustfs/src/storage/rpc/health.rs|infra->app|crate::app::context::resolve_local_node_name|RPC health labels node identity through AppContext resolver
|
||||
accepted|rustfs/src/storage/rpc/node_service.rs|infra->app|crate::app::context::resolve_iam_handle|node RPC IAM operations use AppContext resolver fallback
|
||||
accepted|rustfs/src/storage/rpc/node_service.rs|infra->app|crate::app::context::resolve_lock_client|node RPC locking uses AppContext resolver fallback
|
||||
accepted|rustfs/src/storage/rpc/node_service.rs|infra->interface|crate::admin::service::config::reload_dynamic_config_runtime_state|node RPC reloads admin runtime state
|
||||
accepted|rustfs/src/storage/rpc/node_service.rs|infra->interface|crate::admin::service::config::reload_runtime_config_snapshot|node RPC reloads admin runtime state
|
||||
accepted|rustfs/src/storage/rpc/node_service.rs|infra->interface|crate::admin::service::site_replication::reload_site_replication_runtime_state|node RPC reloads admin runtime state
|
||||
|
||||
Reference in New Issue
Block a user