bucketwarden-server 0.1.0

BucketWarden storage server runtime.
Documentation
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()
    }
}