diff --git a/ecstore/src/bucket/metadata.rs b/ecstore/src/bucket/metadata.rs index c7150691..316e5f5b 100644 --- a/ecstore/src/bucket/metadata.rs +++ b/ecstore/src/bucket/metadata.rs @@ -1,7 +1,11 @@ +use byteorder::{BigEndian, ByteOrder}; +use rmp_serde::Serializer as rmpSerializer; +use serde::Serializer; +use serde::{Deserialize, Deserializer, Serialize}; use std::collections::HashMap; - -use rmp_serde::Serializer; -use serde::{Deserialize, Serialize}; +use std::fmt::Display; +use std::str::FromStr; +use time::macros::datetime; use time::OffsetDateTime; use super::{ @@ -12,17 +16,18 @@ use super::{ use crate::error::Result; use crate::disk::BUCKET_META_PREFIX; +use crate::utils::crypto::hex; pub const BUCKET_METADATA_FILE: &str = ".metadata.bin"; pub const BUCKET_METADATA_FORMAT: u16 = 1; pub const BUCKET_METADATA_VERSION: u16 = 1; -#[derive(Debug, Deserialize, Serialize, Default)] +#[derive(Debug, Deserialize, Serialize)] +#[serde(rename_all = "PascalCase", default)] pub struct BucketMetadata { - format: u16, - version: u16, pub name: String, - pub created: Option, + #[serde(serialize_with = "write_times")] + pub created: OffsetDateTime, pub lock_enabled: bool, // 虽然标记为不使用,但可能需要保留 pub policy_config_json: Vec, pub notification_config_xml: Vec, @@ -36,40 +41,103 @@ pub struct BucketMetadata { pub bucket_targets_config_json: Vec, pub bucket_targets_config_meta_json: Vec, - pub policy_config_updated_at: Option, - pub object_lock_config_updated_at: Option, - pub encryption_config_updated_at: Option, - pub tagging_config_updated_at: Option, - pub quota_config_updated_at: Option, - pub replication_config_updated_at: Option, - pub versioning_config_updated_at: Option, - pub lifecycle_config_updated_at: Option, - pub notification_config_updated_at: Option, - pub bucket_targets_config_updated_at: Option, - pub bucket_targets_config_meta_updated_at: Option, + #[serde(serialize_with = "write_times")] + pub policy_config_updated_at: OffsetDateTime, + #[serde(serialize_with = "write_times")] + pub object_lock_config_updated_at: OffsetDateTime, + #[serde(serialize_with = "write_times")] + pub encryption_config_updated_at: OffsetDateTime, + #[serde(serialize_with = "write_times")] + pub tagging_config_updated_at: OffsetDateTime, + #[serde(serialize_with = "write_times")] + pub quota_config_updated_at: OffsetDateTime, + #[serde(serialize_with = "write_times")] + pub replication_config_updated_at: OffsetDateTime, + #[serde(serialize_with = "write_times")] + pub versioning_config_updated_at: OffsetDateTime, + #[serde(serialize_with = "write_times")] + pub lifecycle_config_updated_at: OffsetDateTime, + #[serde(serialize_with = "write_times")] + pub notification_config_updated_at: OffsetDateTime, + #[serde(serialize_with = "write_times")] + pub bucket_targets_config_updated_at: OffsetDateTime, + #[serde(serialize_with = "write_times")] + pub bucket_targets_config_meta_updated_at: OffsetDateTime, - // 新增UpdatedAt字段 - pub new_field_updated_at: Option, + #[serde(skip)] + pub new_field_updated_at: OffsetDateTime, - // 私有字段,需要原子更新 - pub policy_config: Option, // 假设Policy是一个已经定义好的结构体 + #[serde(skip)] + pub policy_config: Option, + #[serde(skip)] pub notification_config: Option, + #[serde(skip)] pub lifecycle_config: Option, + #[serde(skip)] pub object_lock_config: Option, + #[serde(skip)] pub versioning_config: Option, + #[serde(skip)] pub sse_config: Option, + #[serde(skip)] pub tagging_config: Option, + #[serde(skip)] pub quota_config: Option, + #[serde(skip)] pub replication_config: Option, + #[serde(skip)] pub bucket_target_config: Option, + #[serde(skip)] pub bucket_target_config_meta: Option>, } +impl Default for BucketMetadata { + fn default() -> Self { + Self { + name: Default::default(), + created: OffsetDateTime::UNIX_EPOCH, + lock_enabled: Default::default(), + policy_config_json: Default::default(), + notification_config_xml: Default::default(), + lifecycle_config_xml: Default::default(), + object_lock_config_xml: Default::default(), + versioning_config_xml: Default::default(), + encryption_config_xml: Default::default(), + tagging_config_xml: Default::default(), + quota_config_json: Default::default(), + replication_config_xml: Default::default(), + bucket_targets_config_json: Default::default(), + bucket_targets_config_meta_json: Default::default(), + policy_config_updated_at: OffsetDateTime::UNIX_EPOCH, + object_lock_config_updated_at: OffsetDateTime::UNIX_EPOCH, + encryption_config_updated_at: OffsetDateTime::UNIX_EPOCH, + tagging_config_updated_at: OffsetDateTime::UNIX_EPOCH, + quota_config_updated_at: OffsetDateTime::UNIX_EPOCH, + replication_config_updated_at: OffsetDateTime::UNIX_EPOCH, + versioning_config_updated_at: OffsetDateTime::UNIX_EPOCH, + lifecycle_config_updated_at: OffsetDateTime::UNIX_EPOCH, + notification_config_updated_at: OffsetDateTime::UNIX_EPOCH, + bucket_targets_config_updated_at: OffsetDateTime::UNIX_EPOCH, + bucket_targets_config_meta_updated_at: OffsetDateTime::UNIX_EPOCH, + new_field_updated_at: OffsetDateTime::UNIX_EPOCH, + policy_config: Default::default(), + notification_config: Default::default(), + lifecycle_config: Default::default(), + object_lock_config: Default::default(), + versioning_config: Default::default(), + sse_config: Default::default(), + tagging_config: Default::default(), + quota_config: Default::default(), + replication_config: Default::default(), + bucket_target_config: Default::default(), + bucket_target_config_meta: Default::default(), + } + } +} + impl BucketMetadata { pub fn new(name: &str) -> Self { BucketMetadata { - format: BUCKET_METADATA_FORMAT, - version: BUCKET_METADATA_VERSION, name: name.to_string(), ..Default::default() } @@ -84,10 +152,89 @@ impl BucketMetadata { } pub fn marshal_msg(&self) -> Result> { - unimplemented!() + let mut buf = Vec::new(); + + self.serialize(&mut rmpSerializer::new(&mut buf).with_struct_map())?; + + Ok(buf) } pub fn unmarshal(_buf: &[u8]) -> Result { unimplemented!() } } + +fn deserialize_from_str<'de, S, D>(deserializer: D) -> core::result::Result +where + S: FromStr, + S::Err: Display, + D: Deserializer<'de>, +{ + // let s: String = Deserialize::deserialize(deserializer)?; + // S::from_str(&s).map_err(de::Error::custom) + unimplemented!() +} + +fn write_times(t: &OffsetDateTime, s: S) -> Result +where + S: Serializer, +{ + let mut buf = vec![0x0; 15]; + + let sec = t.unix_timestamp() - 62135596800; + let nsec = t.nanosecond(); + buf[0] = 0xc7; + buf[1] = 0x0c; + buf[2] = 0x05; + BigEndian::write_u64(&mut buf[3..], sec as u64); + BigEndian::write_u32(&mut buf[11..], nsec as u32); + s.serialize_bytes(&buf) +} + +fn write_time(t: OffsetDateTime) -> Result<(), String> { + // let t = t.saturating_sub(0); // 转换为自 UNIX_EPOCH 以来的时间 + println!("t:{:?}", t); + println!("offset:{:?}", datetime!(0-01-01 0:00 UTC)); + + let mut buf = vec![0x0; 15]; + + let sec = t.unix_timestamp() - 62135596800; + let nsec = t.nanosecond(); + + println!("sec:{:?}", sec); + println!("nsec:{:?}", nsec); + + buf[0] = 0xc7; + buf[1] = 0x0c; + buf[2] = 0x05; + // 扩展格式的时间类型 + // buf.push(0xc7); // mext8 + // buf.push(12); // 长度 + // buf.push(0x05); // 时间扩展类型 + + // 将 Unix 时间戳和纳秒部分写入缓冲区 + BigEndian::write_u64(&mut buf[3..], sec as u64); + BigEndian::write_u32(&mut buf[11..], nsec as u32); + + println!("hex:{:?}", hex(buf)); + + Ok(()) +} + +#[cfg(test)] +mod test { + use crate::utils::crypto::hex; + + use super::*; + + #[tokio::test] + async fn marshal_msg() { + // write_time(OffsetDateTime::UNIX_EPOCH).unwrap(); + + let bm = BucketMetadata::new("dada"); + + let buf = bm.marshal_msg().unwrap(); + + println!("{:?}", hex(buf)) + } +} diff --git a/ecstore/src/bucket/msgpkg.md b/ecstore/src/bucket/msgpkg.md new file mode 100644 index 00000000..ff52b1b1 --- /dev/null +++ b/ecstore/src/bucket/msgpkg.md @@ -0,0 +1,31 @@ + +BucketMetadata::new("dada") + +```go +func WriteTime(t time.Time) error { + t = t.UTC() + o :=0 + mw.buf[o] = 0xc7 //mext8 // 0xc7 + mw.buf[o+1] = 12 // 0c + mw.buf[o+2] = 0x05 TimeExtension // 05 + putUnix(mw.buf[o+3:], t.Unix(), int32(t.Nanosecond())) + return nil +} + +// 0001-01-01 00:00:00 +0000 UTC == -62135596800 0 (sec() - 62135596800) -62135596800 c70c0b fffffff1886e090000000000 c70c05 +// 2024-10-01 00:00:00 +0000 UTC == 1727740800 0 0 (sec() - 62135596800) +func putUnix(b []byte, sec int64, nsec int32) { + binary.BigEndian.PutUint64(b, uint64(sec)) + binary.BigEndian.PutUint32(b[8:], uint32(nsec)) +} +``` + +# go + +de0019a44e616d65a464616461a743726561746564c70c05fffffff1886e090000000000ab4c6f636b456e61626c6564c2b0506f6c696379436f6e6669674a534f4ec400b54e6f74696669636174696f6e436f6e666967584d4cc400b24c6966656379636c65436f6e666967584d4cc400b34f626a6563744c6f636b436f6e666967584d4cc400b356657273696f6e696e67436f6e666967584d4cc400b3456e6372797074696f6e436f6e666967584d4cc400b054616767696e67436f6e666967584d4cc400af51756f7461436f6e6669674a534f4ec400b45265706c69636174696f6e436f6e666967584d4cc400b74275636b657454617267657473436f6e6669674a534f4ec400bb4275636b657454617267657473436f6e6669674d6574614a534f4ec400b5506f6c696379436f6e666967557064617465644174c70c05fffffff1886e090000000000b94f626a6563744c6f636b436f6e666967557064617465644174c70c05fffffff1886e090000000000b9456e6372797074696f6e436f6e666967557064617465644174c70c05fffffff1886e090000000000b654616767696e67436f6e666967557064617465644174c70c05fffffff1886e090000000000b451756f7461436f6e666967557064617465644174c70c05fffffff1886e090000000000ba5265706c69636174696f6e436f6e666967557064617465644174c70c05fffffff1886e090000000000b956657273696f6e696e67436f6e666967557064617465644174c70c05fffffff1886e090000000000b84c6966656379636c65436f6e666967557064617465644174c70c05fffffff1886e090000000000bb4e6f74696669636174696f6e436f6e666967557064617465644174c70c05fffffff1886e090000000000bc4275636b657454617267657473436f6e666967557064617465644174c70c05fffffff1886e090000000000d9204275636b657454617267657473436f6e6669674d657461557064617465644174c70c05fffffff1886e090000000000 + +de0019a44e616d65a464616461a743726561746564 c40f c70c05fffffff1886e090000000000ab4c6f636b456e61626c6564c2b0506f6c696379436f6e6669674a736f6e90b54e6f74696669636174696f6e436f6e666967586d6c90b24c6966656379636c65436f6e666967586d6c90b34f626a6563744c6f636b436f6e666967586d6c90b356657273696f6e696e67436f6e666967586d6c90b3456e6372797074696f6e436f6e666967586d6c90b054616767696e67436f6e666967586d6c90af51756f7461436f6e6669674a736f6e90b45265706c69636174696f6e436f6e666967586d6c90b74275636b657454617267657473436f6e6669674a736f6e90bb4275636b657454617267657473436f6e6669674d6574614a736f6e90b5506f6c696379436f6e666967557064617465644174c40fc70c05fffffff1886e090000000000b94f626a6563744c6f636b436f6e666967557064617465644174c40fc70c05fffffff1886e090000000000b9456e6372797074696f6e436f6e666967557064617465644174c40fc70c05fffffff1886e090000000000b654616767696e67436f6e666967557064617465644174c40fc70c05fffffff1886e090000000000b451756f7461436f6e666967557064617465644174c40fc70c05fffffff1886e090000000000ba5265706c69636174696f6e436f6e666967557064617465644174c40fc70c05fffffff1886e090000000000b956657273696f6e696e67436f6e666967557064617465644174c40fc70c05fffffff1886e090000000000b84c6966656379636c65436f6e666967557064617465644174c40fc70c05fffffff1886e090000000000bb4e6f74696669636174696f6e436f6e666967557064617465644174c40fc70c05fffffff1886e090000000000bc4275636b657454617267657473436f6e666967557064617465644174c40fc70c05fffffff1886e090000000000d9204275636b657454617267657473436f6e6669674d657461557064617465644174c40fc70c05fffffff1886e090000000000 + +# rust + +de0019a44e616d65 a464616461 a743726561746564 c0 ab4c6f636b456e61626c6564 c2b0506f6c696379436f6e6669674a736f6e90b54e6f74696669636174696f6e436f6e666967586d6c90b24c6966656379636c65436f6e666967586d6c90b34f626a6563744c6f636b436f6e666967586d6c90b356657273696f6e696e67436f6e666967586d6c90b3456e6372797074696f6e436f6e666967586d6c90b054616767696e67436f6e666967586d6c90af51756f7461436f6e6669674a736f6e90b45265706c69636174696f6e436f6e666967586d6c90b74275636b657454617267657473436f6e6669674a736f6e90bb4275636b657454617267657473436f6e6669674d6574614a736f6e90b5506f6c696379436f6e666967557064617465644174c0b94f626a6563744c6f636b436f6e666967557064617465644174c0b9456e6372797074696f6e436f6e666967557064617465644174c0b654616767696e67436f6e666967557064617465644174c0b451756f7461436f6e666967557064617465644174c0ba5265706c69636174696f6e436f6e666967557064617465644174c0b956657273696f6e696e67436f6e666967557064617465644174c0b84c6966656379636c65436f6e666967557064617465644174c0bb4e6f74696669636174696f6e436f6e666967557064617465644174c0bc4275636b657454617267657473436f6e666967557064617465644174c0d9204275636b657454617267657473436f6e6669674d657461557064617465644174c0