mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-17 10:17:55 +00:00
127 lines
4.8 KiB
Rust
127 lines
4.8 KiB
Rust
// Copyright 2024 RustFS Team
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
use s3s::dto::ReplicationConfiguration;
|
|
|
|
use super::replication_config_boundary::ReplicationConfigurationExt as _;
|
|
use super::replication_filemeta_boundary::{
|
|
REPLICATE_INCOMING_DELETE, ReplicateDecision, ReplicationState, version_purge_statuses_map,
|
|
};
|
|
use super::replication_object_config::{ReplicationConfig, check_replicate_delete};
|
|
use super::replication_queue_boundary::DeletedObjectReplicationInfo;
|
|
use super::replication_storage_boundary::{
|
|
DeletedObject, ObjectInfo, ObjectOptions, ObjectToDelete, deleted_object_for_replication,
|
|
};
|
|
|
|
pub(crate) type ReplicationLifecycleConfig = ReplicationConfig;
|
|
|
|
pub(crate) struct ReplicationLifecycleBridge;
|
|
|
|
impl ReplicationLifecycleBridge {
|
|
pub(crate) fn new_config(config: ReplicationConfiguration) -> ReplicationLifecycleConfig {
|
|
ReplicationConfig::new(Some(config), None)
|
|
}
|
|
|
|
pub(crate) fn has_pending_version_purge(
|
|
config: &ReplicationLifecycleConfig,
|
|
object_name: &str,
|
|
version_purge_pending: bool,
|
|
) -> bool {
|
|
version_purge_pending
|
|
&& config
|
|
.config
|
|
.as_ref()
|
|
.is_some_and(|config| config.has_active_rules(object_name, true))
|
|
}
|
|
|
|
pub(crate) async fn check_delete_replication(
|
|
bucket: &str,
|
|
object: &ObjectToDelete,
|
|
source: &ObjectInfo,
|
|
opts: &ObjectOptions,
|
|
) -> ReplicateDecision {
|
|
check_replicate_delete(bucket, object, source, opts, None).await
|
|
}
|
|
|
|
pub(crate) fn version_delete_replication_state(decision: &ReplicateDecision) -> ReplicationState {
|
|
let pending_status = decision.pending_status();
|
|
ReplicationState {
|
|
replicate_decision_str: decision.to_string(),
|
|
version_purge_status_internal: pending_status.clone(),
|
|
purge_targets: version_purge_statuses_map(pending_status.as_deref().unwrap_or_default()),
|
|
..Default::default()
|
|
}
|
|
}
|
|
|
|
pub(crate) async fn schedule_delete(bucket: String, delete_object: DeletedObject) {
|
|
super::replication_pool::schedule_replication_delete(DeletedObjectReplicationInfo {
|
|
delete_object: deleted_object_for_replication(delete_object),
|
|
bucket,
|
|
event_type: REPLICATE_INCOMING_DELETE.to_string(),
|
|
..Default::default()
|
|
})
|
|
.await;
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use s3s::dto::{Destination, ReplicationRule, ReplicationRuleStatus};
|
|
|
|
use super::super::replication_filemeta_boundary::{ReplicateTargetDecision, VersionPurgeStatusType};
|
|
use super::*;
|
|
|
|
fn replication_rule() -> ReplicationRule {
|
|
ReplicationRule {
|
|
delete_marker_replication: None,
|
|
delete_replication: None,
|
|
destination: Destination {
|
|
bucket: "arn:aws:s3:::target-bucket".to_string(),
|
|
..Default::default()
|
|
},
|
|
existing_object_replication: None,
|
|
filter: None,
|
|
id: Some("rule".to_string()),
|
|
prefix: Some(String::new()),
|
|
priority: Some(1),
|
|
source_selection_criteria: None,
|
|
status: ReplicationRuleStatus::from_static(ReplicationRuleStatus::ENABLED),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn has_pending_version_purge_preserves_replication_active_rule_behavior() {
|
|
let config = ReplicationLifecycleBridge::new_config(ReplicationConfiguration {
|
|
role: String::new(),
|
|
rules: vec![replication_rule()],
|
|
});
|
|
|
|
assert!(ReplicationLifecycleBridge::has_pending_version_purge(&config, "logs/object", true));
|
|
assert!(!ReplicationLifecycleBridge::has_pending_version_purge(&config, "logs/object", false));
|
|
}
|
|
|
|
#[test]
|
|
fn version_delete_replication_state_tracks_pending_purge_targets() {
|
|
let target = ReplicateTargetDecision::new("arn:aws:s3:::target".to_string(), true, false);
|
|
let mut decision = ReplicateDecision::new();
|
|
decision.set(target);
|
|
|
|
let state = ReplicationLifecycleBridge::version_delete_replication_state(&decision);
|
|
|
|
assert_eq!(state.version_purge_status_internal.as_deref(), Some("arn:aws:s3:::target=PENDING;"));
|
|
assert!(state.purge_targets.contains_key("arn:aws:s3:::target"));
|
|
assert_eq!(state.purge_targets["arn:aws:s3:::target"], VersionPurgeStatusType::Pending);
|
|
}
|
|
}
|