use super::*;
use std::path::Path;
impl BucketWarden {
pub fn new(config: RuntimeConfig) -> Result<Self, RuntimeError> {
Ok(Self {
buckets: BTreeMap::new(),
policy: Policy::new(),
audit: AuditLog::default(),
kms: LocalXorKms::new(config.key_id, config.key_material)?,
replication: ReplicationLog::default(),
multipart_uploads: BTreeMap::new(),
notification_events: Vec::new(),
compat_sqs_queues: BTreeMap::new(),
compat_sns_topics: BTreeMap::new(),
auth: AuthStore::new(),
tenant_quotas: BTreeMap::new(),
storage_commits: Vec::new(),
console_preferences: BTreeMap::new(),
active_request_scope: None,
clock_epoch_seconds: config.clock_epoch_seconds,
next_version: 1,
next_upload: 1,
next_event: 1,
next_request: 1,
})
}
pub fn set_clock_epoch_seconds(&mut self, now: u64) {
self.clock_epoch_seconds = now;
}
pub fn snapshot(&self) -> RuntimeSnapshot {
RuntimeSnapshot {
schema_version: RuntimeSnapshot::SCHEMA_VERSION,
buckets: self.buckets.clone(),
policy: self.policy.clone(),
audit_events: self.audit.events().to_vec(),
replication_records: self.replication.records().to_vec(),
multipart_uploads: self.multipart_uploads.clone(),
notification_events: self.notification_events.clone(),
auth: self.auth.clone(),
tenant_quotas: self.tenant_quotas.clone(),
storage_commits: self.storage_commits.clone(),
console_preferences: self.console_preferences.clone(),
clock_epoch_seconds: self.clock_epoch_seconds,
next_version: self.next_version,
next_upload: self.next_upload,
next_event: self.next_event,
next_request: self.next_request,
}
}
pub fn snapshot_json(&self) -> Result<String, RuntimeError> {
serde_json::to_string_pretty(&self.snapshot()).map_err(RuntimeError::SnapshotSerialize)
}
pub fn save_snapshot_file(&self, path: impl AsRef<Path>) -> Result<(), RuntimeError> {
let path = path.as_ref();
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)
.map_err(|error| RuntimeError::SnapshotIo(error.to_string()))?;
}
std::fs::write(path, self.snapshot_json()?)
.map_err(|error| RuntimeError::SnapshotIo(error.to_string()))
}
pub fn restore(
config: RuntimeConfig,
mut snapshot: RuntimeSnapshot,
) -> Result<Self, RuntimeError> {
snapshot.normalize_object_version_ordinals();
snapshot.validate()?;
Ok(Self {
buckets: snapshot.buckets,
policy: snapshot.policy,
audit: AuditLog::from_events(snapshot.audit_events),
kms: LocalXorKms::new(config.key_id, config.key_material)?,
replication: ReplicationLog::from_records(snapshot.replication_records),
multipart_uploads: snapshot.multipart_uploads,
notification_events: snapshot.notification_events,
compat_sqs_queues: BTreeMap::new(),
compat_sns_topics: BTreeMap::new(),
auth: snapshot.auth,
tenant_quotas: snapshot.tenant_quotas,
storage_commits: snapshot.storage_commits,
console_preferences: snapshot.console_preferences,
active_request_scope: None,
clock_epoch_seconds: snapshot.clock_epoch_seconds,
next_version: snapshot.next_version,
next_upload: snapshot.next_upload,
next_event: snapshot.next_event,
next_request: snapshot.next_request,
})
}
pub fn restore_json(config: RuntimeConfig, json: &str) -> Result<Self, RuntimeError> {
let snapshot = serde_json::from_str(json).map_err(RuntimeError::SnapshotDeserialize)?;
Self::restore(config, snapshot)
}
pub fn restore_snapshot_file(
config: RuntimeConfig,
path: impl AsRef<Path>,
) -> Result<Self, RuntimeError> {
let json = std::fs::read_to_string(path)
.map_err(|error| RuntimeError::SnapshotIo(error.to_string()))?;
Self::restore_json(config, &json)
}
pub fn protocol_surface_report(&self) -> ProtocolSurfaceReport {
protocol_surface_report()
}
pub fn client_compatibility_report(&self) -> ClientCompatibilityReport {
client_compatibility_report()
}
pub fn api_operation_report(&self) -> ApiOperationReport {
api_operation_report()
}
pub fn bucket_control_report(&self) -> BucketControlReport {
bucket_control_report()
}
pub fn object_data_report(&self) -> ObjectDataReport {
object_data_report()
}
}