mirror of
https://github.com/rustfs/rustfs.git
synced 2026-07-26 16:28:15 +00:00
refactor: use relative local compat consumers (#3723)
This commit is contained in:
@@ -5,16 +5,17 @@ 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-root-compat-relative-consumers`
|
||||
- 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`.
|
||||
- Based on: API-108 slice.
|
||||
- Branch: `overtrue/arch-rustfs-local-compat-consumers`
|
||||
- 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`.
|
||||
- Based on: API-109 slice.
|
||||
- PR type for this branch: `pure-move`
|
||||
- Runtime behavior changes: none.
|
||||
- Rust code changes: collapse crate-qualified root compatibility and storage
|
||||
owner compatibility consumer paths into relative `super::`/`self::` paths.
|
||||
- CI/script changes: guard selected RustFS root and storage owner consumers
|
||||
- Rust code changes: collapse crate-qualified RustFS app/admin/storage local
|
||||
compatibility consumer paths into relative `super::`/`super::super::` paths.
|
||||
- CI/script changes: guard selected RustFS app/admin/storage local consumers
|
||||
against crate-qualified compatibility paths.
|
||||
- Docs changes: record the API-109 relative compatibility consumer cleanup.
|
||||
- Docs changes: record the API-110 relative local compatibility consumer
|
||||
cleanup.
|
||||
|
||||
## Phase 0 Tasks
|
||||
|
||||
@@ -558,6 +559,18 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
|
||||
compatibility consumer residual scans, migration and layer guards,
|
||||
formatting, diff hygiene, Rust risk scan, pre-commit quality gate, and
|
||||
three-expert review.
|
||||
- [x] `API-110` Collapse RustFS local compatibility consumer paths.
|
||||
- Completed slice: replace crate-qualified app usecase, admin router, and
|
||||
storage ECFS test compatibility consumers with relative owner paths.
|
||||
- Acceptance: selected RustFS app/admin/storage consumers no longer point back
|
||||
to local compatibility facades through crate-qualified paths; migration
|
||||
rules reject regressions.
|
||||
- Must preserve: app object/bucket/multipart/admin usecase behavior,
|
||||
lifecycle transition and capacity tests, admin replication/router helpers,
|
||||
and storage ECFS test coverage.
|
||||
- Verification: RustFS test-target compile coverage, local compatibility
|
||||
consumer residual scan, migration and layer guards, formatting, diff
|
||||
hygiene, Rust risk scan, pre-commit quality gate, and three-expert review.
|
||||
- [x] `G-012` Inventory placement and repair invariants.
|
||||
- Acceptance:
|
||||
[`placement-repair-invariants.md`](placement-repair-invariants.md) records
|
||||
@@ -3591,14 +3604,26 @@ Status values: `[ ]` not started, `[~]` in progress, `[x]` complete, `[!]` block
|
||||
|
||||
| Expert | Status | Notes |
|
||||
|---|---|---|
|
||||
| Quality/architecture | pass | API-109 keeps selected root and storage owner compatibility consumers owner-relative by replacing crate-qualified compatibility paths with scoped `super::` or `self::` paths. |
|
||||
| Migration preservation | pass | The new guards reject crate-qualified root compatibility and storage owner compatibility consumer paths while preserving the same local facade names and aliases. |
|
||||
| Testing/verification | pass | Focused compile, root/storage owner residual scans, migration guard, layer guard, formatting, diff hygiene, risk scan, and full pre-commit passed. |
|
||||
| Quality/architecture | pass | API-110 keeps selected app/admin/storage local compatibility consumers owner-relative by replacing crate-qualified compatibility paths with scoped `super::` or `super::super::` paths. |
|
||||
| Migration preservation | pass | The new guard rejects crate-qualified app/admin/storage local compatibility consumer paths while preserving the same facade names and aliases. |
|
||||
| Testing/verification | pass | Focused compile, local compatibility consumer residual scan, migration guard, layer guard, formatting, diff hygiene, risk scan, and full pre-commit passed. |
|
||||
|
||||
## Verification Notes
|
||||
|
||||
Passed before push:
|
||||
|
||||
- Issue #660 API-110 current slice:
|
||||
- `cargo check -p rustfs --tests`: 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.
|
||||
- RustFS local compatibility consumer residual scan: passed.
|
||||
- Rust risk scan on changed Rust files and guard script: passed.
|
||||
- `make pre-commit`: passed.
|
||||
|
||||
- Issue #660 API-109 current slice:
|
||||
- `cargo check -p rustfs --tests`: passed.
|
||||
- `cargo fmt --all`: passed.
|
||||
|
||||
+27
-29
@@ -12,25 +12,25 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::admin::console::{is_console_path, make_console_server};
|
||||
use crate::admin::handlers::oidc::is_oidc_path;
|
||||
use crate::admin::router_storage_compat::GLOBAL_BOOT_TIME;
|
||||
use crate::admin::router_storage_compat::PeerRestClient;
|
||||
use crate::admin::router_storage_compat::bandwidth::monitor::BandwidthDetails;
|
||||
use crate::admin::router_storage_compat::bucket_target_sys::{
|
||||
use super::router_storage_compat::GLOBAL_BOOT_TIME;
|
||||
use super::router_storage_compat::PeerRestClient;
|
||||
use super::router_storage_compat::bandwidth::monitor::BandwidthDetails;
|
||||
use super::router_storage_compat::bucket_target_sys::{
|
||||
BucketTargetSys, PutObjectOptions, RemoveObjectOptions, S3ClientError, TargetClient,
|
||||
};
|
||||
use crate::admin::router_storage_compat::get_global_notification_sys;
|
||||
use crate::admin::router_storage_compat::metadata::BUCKET_TARGETS_FILE;
|
||||
use crate::admin::router_storage_compat::metadata_sys;
|
||||
use crate::admin::router_storage_compat::read_admin_config_without_migrate;
|
||||
use crate::admin::router_storage_compat::replication::{
|
||||
use super::router_storage_compat::get_global_notification_sys;
|
||||
use super::router_storage_compat::metadata::BUCKET_TARGETS_FILE;
|
||||
use super::router_storage_compat::metadata_sys;
|
||||
use super::router_storage_compat::read_admin_config_without_migrate;
|
||||
use super::router_storage_compat::replication::{
|
||||
BucketReplicationResyncStatus, BucketStats, GLOBAL_REPLICATION_STATS, ObjectOpts, ResyncOpts, get_global_replication_pool,
|
||||
};
|
||||
use crate::admin::router_storage_compat::target::{BucketTarget, BucketTargetType, BucketTargets};
|
||||
use crate::admin::router_storage_compat::versioning_sys::BucketVersioningSys;
|
||||
use crate::admin::router_storage_compat::{AdminReplicationConfigExt as _, AdminVersioningConfigExt as _};
|
||||
use crate::admin::router_storage_compat::{get_global_bucket_monitor, get_global_deployment_id, get_global_region};
|
||||
use super::router_storage_compat::target::{BucketTarget, BucketTargetType, BucketTargets};
|
||||
use super::router_storage_compat::versioning_sys::BucketVersioningSys;
|
||||
use super::router_storage_compat::{AdminReplicationConfigExt as _, AdminVersioningConfigExt as _};
|
||||
use super::router_storage_compat::{get_global_bucket_monitor, get_global_deployment_id, get_global_region};
|
||||
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;
|
||||
use crate::app::object_usecase::DefaultObjectUsecase;
|
||||
use crate::auth::{check_key_valid, get_session_token};
|
||||
@@ -1419,9 +1419,7 @@ async fn ensure_replication_bucket_exists(bucket: &str) -> S3Result<()> {
|
||||
async fn ensure_replication_config_exists(bucket: &str) -> S3Result<()> {
|
||||
match metadata_sys::get_replication_config(bucket).await {
|
||||
Ok(_) => Ok(()),
|
||||
Err(crate::admin::router_storage_compat::StorageError::ConfigNotFound) => {
|
||||
Err(s3_error!(ReplicationConfigurationNotFoundError))
|
||||
}
|
||||
Err(super::router_storage_compat::StorageError::ConfigNotFound) => Err(s3_error!(ReplicationConfigurationNotFoundError)),
|
||||
Err(err) => Err(ApiError::from(err).into()),
|
||||
}
|
||||
}
|
||||
@@ -1946,7 +1944,7 @@ async fn resolve_replication_target_client(bucket: &str, target: &BucketTarget)
|
||||
|
||||
fn build_replication_probe_put_options(now: OffsetDateTime) -> PutObjectOptions {
|
||||
PutObjectOptions {
|
||||
internal: crate::admin::router_storage_compat::bucket_target_sys::AdvancedPutOptions {
|
||||
internal: super::router_storage_compat::bucket_target_sys::AdvancedPutOptions {
|
||||
source_version_id: Uuid::new_v4().to_string(),
|
||||
replication_status: ReplicationStatusType::Replica,
|
||||
source_mtime: now,
|
||||
@@ -2061,7 +2059,7 @@ async fn source_bucket_requires_object_lock(bucket: &str) -> S3Result<bool> {
|
||||
.object_lock_enabled
|
||||
.as_ref()
|
||||
.is_some_and(|state| state.as_str() == s3s::dto::ObjectLockEnabled::ENABLED)),
|
||||
Err(crate::admin::router_storage_compat::StorageError::ConfigNotFound) => Ok(false),
|
||||
Err(super::router_storage_compat::StorageError::ConfigNotFound) => Ok(false),
|
||||
Err(err) => Err(ApiError::from(err).into()),
|
||||
}
|
||||
}
|
||||
@@ -2775,7 +2773,7 @@ mod tests {
|
||||
#[test]
|
||||
fn apply_replication_reset_to_targets_updates_matching_target() {
|
||||
let mut targets = BucketTargets {
|
||||
targets: vec![crate::admin::router_storage_compat::target::BucketTarget {
|
||||
targets: vec![super::super::router_storage_compat::target::BucketTarget {
|
||||
arn: "arn:target".to_string(),
|
||||
..Default::default()
|
||||
}],
|
||||
@@ -2797,10 +2795,10 @@ mod tests {
|
||||
let mut status = BucketReplicationResyncStatus::new();
|
||||
status.targets_map.insert(
|
||||
"arn:z".to_string(),
|
||||
crate::admin::router_storage_compat::replication::TargetReplicationResyncStatus {
|
||||
super::super::router_storage_compat::replication::TargetReplicationResyncStatus {
|
||||
resync_id: "rid-z".to_string(),
|
||||
last_update: Some(datetime!(2025-01-03 00:00 UTC)),
|
||||
resync_status: crate::admin::router_storage_compat::replication::ResyncStatusType::ResyncFailed,
|
||||
resync_status: super::super::router_storage_compat::replication::ResyncStatusType::ResyncFailed,
|
||||
failed_count: 2,
|
||||
failed_size: 4,
|
||||
bucket: "bucket-z".to_string(),
|
||||
@@ -2810,10 +2808,10 @@ mod tests {
|
||||
);
|
||||
status.targets_map.insert(
|
||||
"arn:a".to_string(),
|
||||
crate::admin::router_storage_compat::replication::TargetReplicationResyncStatus {
|
||||
super::super::router_storage_compat::replication::TargetReplicationResyncStatus {
|
||||
resync_id: "rid-a".to_string(),
|
||||
last_update: Some(datetime!(2025-01-02 00:00 UTC)),
|
||||
resync_status: crate::admin::router_storage_compat::replication::ResyncStatusType::ResyncCompleted,
|
||||
resync_status: super::super::router_storage_compat::replication::ResyncStatusType::ResyncCompleted,
|
||||
replicated_count: 3,
|
||||
replicated_size: 9,
|
||||
bucket: "bucket-a".to_string(),
|
||||
@@ -2843,10 +2841,10 @@ mod tests {
|
||||
let mut status = BucketReplicationResyncStatus::new();
|
||||
status.targets_map.insert(
|
||||
"arn:z".to_string(),
|
||||
crate::admin::router_storage_compat::replication::TargetReplicationResyncStatus {
|
||||
super::super::router_storage_compat::replication::TargetReplicationResyncStatus {
|
||||
resync_id: "rid-z".to_string(),
|
||||
last_update: Some(datetime!(2025-02-03 00:00 UTC)),
|
||||
resync_status: crate::admin::router_storage_compat::replication::ResyncStatusType::ResyncFailed,
|
||||
resync_status: super::super::router_storage_compat::replication::ResyncStatusType::ResyncFailed,
|
||||
failed_count: 2,
|
||||
failed_size: 4,
|
||||
bucket: "bucket-z".to_string(),
|
||||
@@ -2856,10 +2854,10 @@ mod tests {
|
||||
);
|
||||
status.targets_map.insert(
|
||||
"arn:a".to_string(),
|
||||
crate::admin::router_storage_compat::replication::TargetReplicationResyncStatus {
|
||||
super::super::router_storage_compat::replication::TargetReplicationResyncStatus {
|
||||
resync_id: "rid-a".to_string(),
|
||||
last_update: Some(datetime!(2025-02-02 00:00 UTC)),
|
||||
resync_status: crate::admin::router_storage_compat::replication::ResyncStatusType::ResyncCompleted,
|
||||
resync_status: super::super::router_storage_compat::replication::ResyncStatusType::ResyncCompleted,
|
||||
replicated_count: 3,
|
||||
replicated_size: 9,
|
||||
bucket: "bucket-a".to_string(),
|
||||
|
||||
@@ -14,14 +14,14 @@
|
||||
|
||||
//! Admin application use-case contracts.
|
||||
|
||||
use crate::app::context::{AppContext, get_global_app_context, resolve_object_store_handle_for_context};
|
||||
use crate::app::usecase_storage_compat::ECStore;
|
||||
use crate::app::usecase_storage_compat::EndpointServerPools;
|
||||
use crate::app::usecase_storage_compat::get_server_info;
|
||||
use crate::app::usecase_storage_compat::{
|
||||
use super::usecase_storage_compat::ECStore;
|
||||
use super::usecase_storage_compat::EndpointServerPools;
|
||||
use super::usecase_storage_compat::get_server_info;
|
||||
use super::usecase_storage_compat::{
|
||||
PoolDecommissionInfo, PoolStatus, get_total_usable_capacity, get_total_usable_capacity_free,
|
||||
};
|
||||
use crate::app::usecase_storage_compat::{apply_bucket_usage_memory_overlay, load_data_usage_from_backend};
|
||||
use super::usecase_storage_compat::{apply_bucket_usage_memory_overlay, load_data_usage_from_backend};
|
||||
use crate::app::context::{AppContext, get_global_app_context, resolve_object_store_handle_for_context};
|
||||
use crate::capacity::resolve_admin_used_capacity;
|
||||
use crate::error::ApiError;
|
||||
use crate::server::{DependencyReadiness, collect_dependency_readiness as collect_runtime_dependency_readiness};
|
||||
@@ -403,8 +403,8 @@ impl DefaultAdminUsecase {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::super::usecase_storage_compat::{PoolDecommissionInfo, PoolStatus};
|
||||
use super::*;
|
||||
use crate::app::usecase_storage_compat::{PoolDecommissionInfo, PoolStatus};
|
||||
use time::OffsetDateTime;
|
||||
|
||||
#[tokio::test]
|
||||
|
||||
@@ -14,18 +14,12 @@
|
||||
|
||||
//! Bucket application use-case contracts.
|
||||
|
||||
use crate::admin::handlers::site_replication::{
|
||||
site_replication_bucket_meta_hook, site_replication_delete_bucket_hook, site_replication_make_bucket_hook,
|
||||
};
|
||||
use crate::app::context::{
|
||||
AppContext, default_notify_interface, get_global_app_context, resolve_object_store_handle_for_context,
|
||||
};
|
||||
use crate::app::usecase_storage_compat::ECStore;
|
||||
use crate::app::usecase_storage_compat::StorageError;
|
||||
use crate::app::usecase_storage_compat::get_global_notification_sys;
|
||||
use crate::app::usecase_storage_compat::object_api_utils::to_s3s_etag;
|
||||
use crate::app::usecase_storage_compat::{AppObjectLockConfigExt as _, AppVersioningConfigExt as _};
|
||||
use crate::app::usecase_storage_compat::{
|
||||
use super::usecase_storage_compat::ECStore;
|
||||
use super::usecase_storage_compat::StorageError;
|
||||
use super::usecase_storage_compat::get_global_notification_sys;
|
||||
use super::usecase_storage_compat::object_api_utils::to_s3s_etag;
|
||||
use super::usecase_storage_compat::{AppObjectLockConfigExt as _, AppVersioningConfigExt as _};
|
||||
use super::usecase_storage_compat::{
|
||||
bucket_target_sys::BucketTargetSys,
|
||||
lifecycle::bucket_lifecycle_ops::{
|
||||
enqueue_expiry_for_existing_objects, enqueue_transition_for_existing_objects, validate_lifecycle_config,
|
||||
@@ -42,6 +36,12 @@ use crate::app::usecase_storage_compat::{
|
||||
utils::serialize,
|
||||
versioning_sys::BucketVersioningSys,
|
||||
};
|
||||
use crate::admin::handlers::site_replication::{
|
||||
site_replication_bucket_meta_hook, site_replication_delete_bucket_hook, site_replication_make_bucket_hook,
|
||||
};
|
||||
use crate::app::context::{
|
||||
AppContext, default_notify_interface, get_global_app_context, resolve_object_store_handle_for_context,
|
||||
};
|
||||
use crate::auth::get_condition_values_with_client_info;
|
||||
use crate::error::ApiError;
|
||||
use crate::server::RemoteAddr;
|
||||
@@ -2285,7 +2285,7 @@ mod tests {
|
||||
BucketTargets {
|
||||
targets: arns
|
||||
.iter()
|
||||
.map(|arn| crate::app::usecase_storage_compat::target::BucketTarget {
|
||||
.map(|arn| super::super::usecase_storage_compat::target::BucketTarget {
|
||||
arn: (*arn).to_string(),
|
||||
target_type: BucketTargetType::ReplicationService,
|
||||
..Default::default()
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::app::usecase_storage_compat::{ECStore, Endpoint, EndpointServerPools, Endpoints, PoolEndpoints, metadata_sys};
|
||||
use super::usecase_storage_compat::{ECStore, Endpoint, EndpointServerPools, Endpoints, PoolEndpoints, metadata_sys};
|
||||
use rustfs_common::heal_channel::{HealOpts, HealScanMode};
|
||||
use rustfs_object_capacity::capacity_manager::{HybridStrategyConfig, create_isolated_manager};
|
||||
use rustfs_storage_api::{BucketOperations, BucketOptions, HealOperations as _, MakeBucketOptions, ObjectIO as _};
|
||||
@@ -77,7 +77,7 @@ async fn setup_capacity_dirty_scope_env() -> (Vec<PathBuf>, Arc<ECStore>) {
|
||||
};
|
||||
|
||||
let endpoint_pools = EndpointServerPools(vec![pool_endpoints]);
|
||||
crate::app::usecase_storage_compat::init_local_disks(endpoint_pools.clone())
|
||||
super::usecase_storage_compat::init_local_disks(endpoint_pools.clone())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
|
||||
@@ -12,9 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use super::{multipart_usecase::DefaultMultipartUsecase, object_usecase::DefaultObjectUsecase};
|
||||
use crate::app::bucket_usecase::DefaultBucketUsecase;
|
||||
use crate::app::usecase_storage_compat::{
|
||||
use super::usecase_storage_compat::{
|
||||
AppWarmBackend, ECStore, Endpoint, EndpointServerPools, Endpoints, GLOBAL_TierConfigMgr, PoolEndpoints, TierConfig, TierType,
|
||||
WarmBackendGetOpts,
|
||||
metadata::{BUCKET_LIFECYCLE_CONFIG, OBJECT_LOCK_CONFIG},
|
||||
@@ -22,6 +20,8 @@ use crate::app::usecase_storage_compat::{
|
||||
object_api_utils::to_s3s_etag,
|
||||
transition_api::{ReadCloser, ReaderImpl},
|
||||
};
|
||||
use super::{multipart_usecase::DefaultMultipartUsecase, object_usecase::DefaultObjectUsecase};
|
||||
use crate::app::bucket_usecase::DefaultBucketUsecase;
|
||||
use crate::storage::ecfs::FS;
|
||||
use crate::storage::{
|
||||
StorageObjectInfo as ObjectInfo, StorageObjectOptions as ObjectOptions, StoragePutObjReader as PutObjReader,
|
||||
@@ -107,7 +107,7 @@ async fn setup_test_env() -> (Vec<PathBuf>, Arc<ECStore>) {
|
||||
|
||||
let endpoint_pools = EndpointServerPools(vec![pool_endpoints]);
|
||||
|
||||
crate::app::usecase_storage_compat::init_local_disks(endpoint_pools.clone())
|
||||
super::usecase_storage_compat::init_local_disks(endpoint_pools.clone())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
@@ -126,7 +126,7 @@ async fn setup_test_env() -> (Vec<PathBuf>, Arc<ECStore>) {
|
||||
let buckets = buckets_list.into_iter().map(|v| v.name).collect();
|
||||
metadata_sys::init_bucket_metadata_sys(ecstore.clone(), buckets).await;
|
||||
|
||||
crate::app::usecase_storage_compat::lifecycle::bucket_lifecycle_ops::init_background_expiry(ecstore.clone()).await;
|
||||
super::usecase_storage_compat::lifecycle::bucket_lifecycle_ops::init_background_expiry(ecstore.clone()).await;
|
||||
|
||||
let _ = GLOBAL_ENV.set((disk_paths.clone(), ecstore.clone()));
|
||||
|
||||
@@ -926,7 +926,7 @@ async fn delete_transitioned_object_removes_remote_tier_copy_via_usecase() {
|
||||
.expect("Failed to set lifecycle configuration");
|
||||
let _ = upload_test_object(&ecstore, bucket.as_str(), object, payload).await;
|
||||
|
||||
crate::app::usecase_storage_compat::lifecycle::bucket_lifecycle_ops::enqueue_transition_for_existing_objects(
|
||||
super::usecase_storage_compat::lifecycle::bucket_lifecycle_ops::enqueue_transition_for_existing_objects(
|
||||
ecstore.clone(),
|
||||
bucket.as_str(),
|
||||
)
|
||||
@@ -986,7 +986,7 @@ async fn lifecycle_transition_marks_dirty_disks_for_capacity_manager() {
|
||||
.expect("Failed to set lifecycle configuration");
|
||||
let _ = upload_test_object(&ecstore, bucket.as_str(), object, payload).await;
|
||||
|
||||
crate::app::usecase_storage_compat::lifecycle::bucket_lifecycle_ops::enqueue_transition_for_existing_objects(
|
||||
super::usecase_storage_compat::lifecycle::bucket_lifecycle_ops::enqueue_transition_for_existing_objects(
|
||||
ecstore.clone(),
|
||||
bucket.as_str(),
|
||||
)
|
||||
|
||||
@@ -14,24 +14,24 @@
|
||||
|
||||
//! Multipart application use-case contracts.
|
||||
|
||||
use crate::app::context::{AppContext, get_global_app_context, resolve_object_store_handle_for_context};
|
||||
use crate::app::object_usecase::{build_put_like_object_lock_metadata, validate_existing_object_lock_for_write};
|
||||
use crate::app::usecase_storage_compat::ECStore;
|
||||
use crate::app::usecase_storage_compat::is_disk_compressible;
|
||||
use crate::app::usecase_storage_compat::is_valid_storage_class;
|
||||
use crate::app::usecase_storage_compat::object_api_utils::to_s3s_etag;
|
||||
use crate::app::usecase_storage_compat::quota::checker::QuotaChecker;
|
||||
use super::usecase_storage_compat::ECStore;
|
||||
use super::usecase_storage_compat::is_disk_compressible;
|
||||
use super::usecase_storage_compat::is_valid_storage_class;
|
||||
use super::usecase_storage_compat::object_api_utils::to_s3s_etag;
|
||||
use super::usecase_storage_compat::quota::checker::QuotaChecker;
|
||||
#[cfg(test)]
|
||||
use crate::app::usecase_storage_compat::{DecryptReader, EncryptReader, HardLimitReader, boxed_reader, wrap_reader};
|
||||
use crate::app::usecase_storage_compat::{HashReader, WritePlan};
|
||||
use crate::app::usecase_storage_compat::{StorageError, is_err_object_not_found, is_err_version_not_found};
|
||||
use crate::app::usecase_storage_compat::{
|
||||
use super::usecase_storage_compat::{DecryptReader, EncryptReader, HardLimitReader, boxed_reader, wrap_reader};
|
||||
use super::usecase_storage_compat::{HashReader, WritePlan};
|
||||
use super::usecase_storage_compat::{StorageError, is_err_object_not_found, is_err_version_not_found};
|
||||
use super::usecase_storage_compat::{
|
||||
lifecycle::{bucket_lifecycle_audit::LcEventSrc, bucket_lifecycle_ops::enqueue_transition_immediate},
|
||||
metadata_sys,
|
||||
quota::QuotaOperation,
|
||||
replication::{get_must_replicate_options, must_replicate, schedule_replication},
|
||||
versioning_sys::BucketVersioningSys,
|
||||
};
|
||||
use crate::app::context::{AppContext, get_global_app_context, resolve_object_store_handle_for_context};
|
||||
use crate::app::object_usecase::{build_put_like_object_lock_metadata, validate_existing_object_lock_for_write};
|
||||
use crate::capacity::record_capacity_write;
|
||||
use crate::error::ApiError;
|
||||
use crate::storage::access::has_bypass_governance_header;
|
||||
@@ -482,7 +482,7 @@ impl DefaultMultipartUsecase {
|
||||
));
|
||||
}
|
||||
// Update quota tracking after successful multipart upload
|
||||
crate::app::usecase_storage_compat::record_bucket_object_write_memory(
|
||||
super::usecase_storage_compat::record_bucket_object_write_memory(
|
||||
&bucket,
|
||||
previous_current_size,
|
||||
obj_info.size.max(0) as u64,
|
||||
@@ -675,7 +675,7 @@ impl DefaultMultipartUsecase {
|
||||
rustfs_utils::http::insert_str(
|
||||
&mut metadata,
|
||||
rustfs_utils::http::SUFFIX_COMPRESSION,
|
||||
crate::app::usecase_storage_compat::compression_metadata_value(CompressionAlgorithm::default()),
|
||||
super::usecase_storage_compat::compression_metadata_value(CompressionAlgorithm::default()),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -894,12 +894,9 @@ impl DefaultMultipartUsecase {
|
||||
.ok_or_else(|| ApiError::from(StorageError::other("Missing SSE-C session material")))?;
|
||||
let ssec_write = match ssec_material.key_kind {
|
||||
crate::storage::sse::EncryptionKeyKind::Object => {
|
||||
crate::app::usecase_storage_compat::WriteEncryption::multipart_object_key(
|
||||
ssec_material.key_bytes,
|
||||
part_id as u32,
|
||||
)
|
||||
super::usecase_storage_compat::WriteEncryption::multipart_object_key(ssec_material.key_bytes, part_id as u32)
|
||||
}
|
||||
crate::storage::sse::EncryptionKeyKind::Direct => crate::app::usecase_storage_compat::WriteEncryption::multipart(
|
||||
crate::storage::sse::EncryptionKeyKind::Direct => super::usecase_storage_compat::WriteEncryption::multipart(
|
||||
ssec_material.key_bytes,
|
||||
ssec_material.base_nonce,
|
||||
part_id,
|
||||
@@ -919,12 +916,12 @@ impl DefaultMultipartUsecase {
|
||||
.ok_or_else(|| ApiError::from(StorageError::other("Missing managed SSE session material")))?;
|
||||
let managed_write = match managed_material.key_kind {
|
||||
crate::storage::sse::EncryptionKeyKind::Object => {
|
||||
crate::app::usecase_storage_compat::WriteEncryption::multipart_object_key(
|
||||
super::usecase_storage_compat::WriteEncryption::multipart_object_key(
|
||||
managed_material.key_bytes,
|
||||
part_id as u32,
|
||||
)
|
||||
}
|
||||
crate::storage::sse::EncryptionKeyKind::Direct => crate::app::usecase_storage_compat::WriteEncryption::multipart(
|
||||
crate::storage::sse::EncryptionKeyKind::Direct => super::usecase_storage_compat::WriteEncryption::multipart(
|
||||
managed_material.key_bytes,
|
||||
managed_material.base_nonce,
|
||||
part_id,
|
||||
@@ -1243,12 +1240,9 @@ impl DefaultMultipartUsecase {
|
||||
.ok_or_else(|| ApiError::from(StorageError::other("Missing SSE-C session material")))?;
|
||||
let ssec_write = match ssec_material.key_kind {
|
||||
crate::storage::sse::EncryptionKeyKind::Object => {
|
||||
crate::app::usecase_storage_compat::WriteEncryption::multipart_object_key(
|
||||
ssec_material.key_bytes,
|
||||
part_id as u32,
|
||||
)
|
||||
super::usecase_storage_compat::WriteEncryption::multipart_object_key(ssec_material.key_bytes, part_id as u32)
|
||||
}
|
||||
crate::storage::sse::EncryptionKeyKind::Direct => crate::app::usecase_storage_compat::WriteEncryption::multipart(
|
||||
crate::storage::sse::EncryptionKeyKind::Direct => super::usecase_storage_compat::WriteEncryption::multipart(
|
||||
ssec_material.key_bytes,
|
||||
ssec_material.base_nonce,
|
||||
part_id,
|
||||
@@ -1272,12 +1266,12 @@ impl DefaultMultipartUsecase {
|
||||
.ok_or_else(|| ApiError::from(StorageError::other("Missing managed SSE session material")))?;
|
||||
let managed_write = match managed_material.key_kind {
|
||||
crate::storage::sse::EncryptionKeyKind::Object => {
|
||||
crate::app::usecase_storage_compat::WriteEncryption::multipart_object_key(
|
||||
super::usecase_storage_compat::WriteEncryption::multipart_object_key(
|
||||
managed_material.key_bytes,
|
||||
part_id as u32,
|
||||
)
|
||||
}
|
||||
crate::storage::sse::EncryptionKeyKind::Direct => crate::app::usecase_storage_compat::WriteEncryption::multipart(
|
||||
crate::storage::sse::EncryptionKeyKind::Direct => super::usecase_storage_compat::WriteEncryption::multipart(
|
||||
managed_material.key_bytes,
|
||||
managed_material.base_nonce,
|
||||
part_id,
|
||||
|
||||
@@ -48,21 +48,21 @@ use metrics::{counter, histogram};
|
||||
use pin_project_lite::pin_project;
|
||||
use rustfs_object_capacity::capacity_manager::get_capacity_manager;
|
||||
// Performance metrics recording (with zero-copy-metrics integration)
|
||||
use crate::app::usecase_storage_compat::ECStore;
|
||||
use crate::app::usecase_storage_compat::object_api_utils::to_s3s_etag;
|
||||
use crate::app::usecase_storage_compat::quota::checker::QuotaChecker;
|
||||
use crate::app::usecase_storage_compat::storageclass;
|
||||
use crate::app::usecase_storage_compat::{
|
||||
use super::usecase_storage_compat::ECStore;
|
||||
use super::usecase_storage_compat::object_api_utils::to_s3s_etag;
|
||||
use super::usecase_storage_compat::quota::checker::QuotaChecker;
|
||||
use super::usecase_storage_compat::storageclass;
|
||||
use super::usecase_storage_compat::{
|
||||
AppReplicationConfigExt as _, AppVersioningConfigExt as _, predict_lifecycle_expiration, validate_restore_request,
|
||||
};
|
||||
use crate::app::usecase_storage_compat::{DiskError, is_all_buckets_not_found};
|
||||
use crate::app::usecase_storage_compat::{DynReader, HashReader, WritePlan, wrap_reader};
|
||||
use crate::app::usecase_storage_compat::{
|
||||
use super::usecase_storage_compat::{DiskError, is_all_buckets_not_found};
|
||||
use super::usecase_storage_compat::{DynReader, HashReader, WritePlan, wrap_reader};
|
||||
use super::usecase_storage_compat::{
|
||||
Error as EcstoreError, StorageError, is_err_bucket_not_found, is_err_object_not_found, is_err_version_not_found,
|
||||
};
|
||||
use crate::app::usecase_storage_compat::{MIN_DISK_COMPRESSIBLE_SIZE, is_disk_compressible};
|
||||
use crate::app::usecase_storage_compat::{get_lock_acquire_timeout, is_valid_storage_class};
|
||||
use crate::app::usecase_storage_compat::{
|
||||
use super::usecase_storage_compat::{MIN_DISK_COMPRESSIBLE_SIZE, is_disk_compressible};
|
||||
use super::usecase_storage_compat::{get_lock_acquire_timeout, is_valid_storage_class};
|
||||
use super::usecase_storage_compat::{
|
||||
lifecycle::{
|
||||
bucket_lifecycle_audit::LcEventSrc,
|
||||
bucket_lifecycle_ops::{enqueue_transition_immediate, post_restore_opts},
|
||||
@@ -279,12 +279,12 @@ async fn enqueue_transitioned_delete_cleanup(
|
||||
let _activity_guard = DeleteTailActivityGuard::new(DeleteTailStage::Cleanup);
|
||||
|
||||
let je = if opts.delete_prefix {
|
||||
crate::app::usecase_storage_compat::lifecycle::tier_sweeper::transitioned_force_delete_journal_entry(
|
||||
super::usecase_storage_compat::lifecycle::tier_sweeper::transitioned_force_delete_journal_entry(
|
||||
&existing.transitioned_object,
|
||||
)
|
||||
} else {
|
||||
let version_id = opts.version_id.as_ref().and_then(|v| Uuid::parse_str(v).ok());
|
||||
crate::app::usecase_storage_compat::lifecycle::tier_sweeper::transitioned_delete_journal_entry(
|
||||
super::usecase_storage_compat::lifecycle::tier_sweeper::transitioned_delete_journal_entry(
|
||||
version_id,
|
||||
opts.versioned,
|
||||
opts.version_suspended,
|
||||
@@ -295,9 +295,9 @@ async fn enqueue_transitioned_delete_cleanup(
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
crate::app::usecase_storage_compat::lifecycle::tier_delete_journal::persist_tier_delete_journal_entry(store, &je).await?;
|
||||
super::usecase_storage_compat::lifecycle::tier_delete_journal::persist_tier_delete_journal_entry(store, &je).await?;
|
||||
|
||||
let mut expiry_state = crate::app::usecase_storage_compat::lifecycle::bucket_lifecycle_ops::GLOBAL_ExpiryState
|
||||
let mut expiry_state = super::usecase_storage_compat::lifecycle::bucket_lifecycle_ops::GLOBAL_ExpiryState
|
||||
.write()
|
||||
.await;
|
||||
if let Err(err) = expiry_state.enqueue_tier_journal_entry(&je).await {
|
||||
@@ -1603,7 +1603,7 @@ impl DefaultObjectUsecase {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
async fn prepare_get_object_read(
|
||||
req: &S3Request<GetObjectInput>,
|
||||
store: &crate::app::usecase_storage_compat::ECStore,
|
||||
store: &super::usecase_storage_compat::ECStore,
|
||||
manager: &ConcurrencyManager,
|
||||
bucket: &str,
|
||||
key: &str,
|
||||
@@ -2197,7 +2197,7 @@ impl DefaultObjectUsecase {
|
||||
insert_str(
|
||||
&mut metadata,
|
||||
SUFFIX_COMPRESSION,
|
||||
crate::app::usecase_storage_compat::compression_metadata_value(algorithm),
|
||||
super::usecase_storage_compat::compression_metadata_value(algorithm),
|
||||
);
|
||||
insert_str(&mut metadata, SUFFIX_ACTUAL_SIZE, size.to_string());
|
||||
|
||||
@@ -2212,7 +2212,7 @@ impl DefaultObjectUsecase {
|
||||
insert_str(
|
||||
&mut opts.user_defined,
|
||||
SUFFIX_COMPRESSION,
|
||||
crate::app::usecase_storage_compat::compression_metadata_value(algorithm),
|
||||
super::usecase_storage_compat::compression_metadata_value(algorithm),
|
||||
);
|
||||
insert_str(&mut opts.user_defined, SUFFIX_ACTUAL_SIZE, size.to_string());
|
||||
|
||||
@@ -2404,7 +2404,7 @@ impl DefaultObjectUsecase {
|
||||
maybe_enqueue_transition_immediate(&obj_info, LcEventSrc::S3PutObject).await;
|
||||
|
||||
// Fast in-memory update for immediate quota and admin usage consistency
|
||||
crate::app::usecase_storage_compat::record_bucket_object_write_memory(
|
||||
super::usecase_storage_compat::record_bucket_object_write_memory(
|
||||
&bucket,
|
||||
previous_current_size,
|
||||
obj_info.size.max(0) as u64,
|
||||
@@ -3274,7 +3274,7 @@ impl DefaultObjectUsecase {
|
||||
insert_str(
|
||||
&mut compress_metadata,
|
||||
SUFFIX_COMPRESSION,
|
||||
crate::app::usecase_storage_compat::compression_metadata_value(CompressionAlgorithm::default()),
|
||||
super::usecase_storage_compat::compression_metadata_value(CompressionAlgorithm::default()),
|
||||
);
|
||||
insert_str(&mut compress_metadata, SUFFIX_ACTUAL_SIZE, actual_size.to_string());
|
||||
} else {
|
||||
@@ -3367,7 +3367,7 @@ impl DefaultObjectUsecase {
|
||||
|
||||
// Update quota tracking after successful copy
|
||||
if has_bucket_metadata {
|
||||
crate::app::usecase_storage_compat::record_bucket_object_write_memory(
|
||||
super::usecase_storage_compat::record_bucket_object_write_memory(
|
||||
&bucket,
|
||||
previous_current_size,
|
||||
oi.size.max(0) as u64,
|
||||
@@ -3649,7 +3649,7 @@ impl DefaultObjectUsecase {
|
||||
);
|
||||
}
|
||||
let size = object_sizes[i].max(0) as u64;
|
||||
crate::app::usecase_storage_compat::record_bucket_object_delete_memory(
|
||||
super::usecase_storage_compat::record_bucket_object_delete_memory(
|
||||
&bucket,
|
||||
size,
|
||||
existing_object_infos[i].is_some() && object_to_delete[i].version_id.is_none(),
|
||||
@@ -3887,7 +3887,7 @@ impl DefaultObjectUsecase {
|
||||
}
|
||||
|
||||
// Fast in-memory update for immediate quota and admin usage consistency
|
||||
crate::app::usecase_storage_compat::record_bucket_object_delete_memory(
|
||||
super::usecase_storage_compat::record_bucket_object_delete_memory(
|
||||
&bucket,
|
||||
obj_info.size.max(0) as u64,
|
||||
opts.version_id.is_none(),
|
||||
@@ -4864,7 +4864,7 @@ impl DefaultObjectUsecase {
|
||||
insert_str(
|
||||
&mut metadata,
|
||||
SUFFIX_COMPRESSION,
|
||||
crate::app::usecase_storage_compat::compression_metadata_value(algorithm),
|
||||
super::usecase_storage_compat::compression_metadata_value(algorithm),
|
||||
);
|
||||
insert_str(&mut metadata, SUFFIX_ACTUAL_SIZE, size.to_string());
|
||||
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::config::WorkloadProfile;
|
||||
use crate::server::cors;
|
||||
use crate::storage::core_storage_compat::{
|
||||
use super::super::core_storage_compat::{
|
||||
BucketMetadata, DEFAULT_READ_BUFFER_SIZE, get_global_bucket_metadata_sys, set_bucket_metadata,
|
||||
};
|
||||
use crate::config::WorkloadProfile;
|
||||
use crate::server::cors;
|
||||
use crate::storage::ecfs::{FS, validate_object_lock_configuration_input};
|
||||
use crate::storage::s3_api::common::{rustfs_initiator, rustfs_owner};
|
||||
use crate::storage::{
|
||||
@@ -941,8 +941,8 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_validate_bucket_object_lock_enabled() {
|
||||
use crate::storage::core_storage_compat::bucket_metadata_sys_initialized;
|
||||
use crate::storage::core_storage_compat::set_bucket_metadata;
|
||||
use super::super::core_storage_compat::bucket_metadata_sys_initialized;
|
||||
use super::super::core_storage_compat::set_bucket_metadata;
|
||||
use s3s::dto::{ObjectLockConfiguration, ObjectLockEnabled};
|
||||
use time::OffsetDateTime;
|
||||
|
||||
@@ -1781,7 +1781,7 @@ mod tests {
|
||||
/// with a single-element vec value, matching the format expected by policy evaluation.
|
||||
#[test]
|
||||
fn test_object_tag_condition_key_format() {
|
||||
use crate::storage::core_storage_compat::decode_tags_to_map;
|
||||
use super::super::core_storage_compat::decode_tags_to_map;
|
||||
use std::collections::HashMap;
|
||||
|
||||
let tags_str = "security=public&project=webapp&env=prod";
|
||||
|
||||
@@ -101,6 +101,7 @@ ALL_STORAGE_COMPAT_SELF_FACADE_PATH_HITS_FILE="${TMP_DIR}/all_storage_compat_sel
|
||||
RUSTFS_LOCAL_COMPAT_OWNER_SELF_PATH_HITS_FILE="${TMP_DIR}/rustfs_local_compat_owner_self_path_hits.txt"
|
||||
RUSTFS_ROOT_COMPAT_RELATIVE_CONSUMER_HITS_FILE="${TMP_DIR}/rustfs_root_compat_relative_consumer_hits.txt"
|
||||
RUSTFS_STORAGE_CORE_COMPAT_RELATIVE_CONSUMER_HITS_FILE="${TMP_DIR}/rustfs_storage_core_compat_relative_consumer_hits.txt"
|
||||
RUSTFS_LOCAL_COMPAT_RELATIVE_CONSUMER_HITS_FILE="${TMP_DIR}/rustfs_local_compat_relative_consumer_hits.txt"
|
||||
SCANNER_BUCKET_STORAGE_COMPAT_MODULE_HITS_FILE="${TMP_DIR}/scanner_bucket_storage_compat_module_hits.txt"
|
||||
NOTIFY_STORAGE_COMPAT_MODULE_HITS_FILE="${TMP_DIR}/notify_storage_compat_module_hits.txt"
|
||||
OBS_STORAGE_COMPAT_PASSTHROUGH_HITS_FILE="${TMP_DIR}/obs_storage_compat_passthrough_hits.txt"
|
||||
@@ -1082,6 +1083,22 @@ if [[ -s "$RUSTFS_STORAGE_CORE_COMPAT_RELATIVE_CONSUMER_HITS_FILE" ]]; then
|
||||
report_failure "RustFS storage owner consumers must use relative core_storage_compat paths instead of crate-qualified storage owner paths: $(paste -sd '; ' "$RUSTFS_STORAGE_CORE_COMPAT_RELATIVE_CONSUMER_HITS_FILE")"
|
||||
fi
|
||||
|
||||
(
|
||||
cd "$ROOT_DIR"
|
||||
{
|
||||
rg -n --with-filename 'crate::app::usecase_storage_compat' \
|
||||
rustfs/src/app/*.rs || true
|
||||
rg -n --with-filename 'crate::admin::router_storage_compat' \
|
||||
rustfs/src/admin/router.rs || true
|
||||
rg -n --with-filename 'crate::storage::core_storage_compat' \
|
||||
rustfs/src/storage/ecfs_test.rs || true
|
||||
}
|
||||
) >"$RUSTFS_LOCAL_COMPAT_RELATIVE_CONSUMER_HITS_FILE"
|
||||
|
||||
if [[ -s "$RUSTFS_LOCAL_COMPAT_RELATIVE_CONSUMER_HITS_FILE" ]]; then
|
||||
report_failure "RustFS local compatibility consumers must use relative owner paths instead of crate-qualified local compatibility paths: $(paste -sd '; ' "$RUSTFS_LOCAL_COMPAT_RELATIVE_CONSUMER_HITS_FILE")"
|
||||
fi
|
||||
|
||||
(
|
||||
cd "$ROOT_DIR"
|
||||
rg -n --no-heading 'pub\(crate\)\s+use rustfs_ecstore::api::bucket::\{[^}]*\b(?:bucket_target_sys|lifecycle|metadata_sys|replication|versioning|versioning_sys)\b[^}]*\}\s*;' \
|
||||
|
||||
Reference in New Issue
Block a user