akka / akka-edge-rs

Akka Edge support in Rust
https://doc.akka.io/docs/akka-edge/current/
Other
9 stars 1 forks source link

Provides a convenience for marshalling declarations #103

Closed huntc closed 1 year ago

huntc commented 1 year ago

Just this:

pub fn to_record_type(event: &Event) -> Option<u32> {
    match event {
        Event::TemperatureRead { .. } => Some(0),
        Event::Registered { .. } => Some(1),
    }
}

...

    let marshaller = cbor::marshaller(
        EntityType::from(ENTITY_TYPE),
        events_key_secret_path,
        secret_store,
        to_record_type,
    );

...was formally this:

pub struct EventEnvelopeMarshaller {
    pub entity_type: EntityType,
    pub events_key_secret_path: Arc<str>,
    pub secret_store: FileSecretStore,
}

const EVENT_TYPE_BIT_SHIFT: usize = 52;
const EVENT_ID_BIT_MASK: u64 = 0xFFFFFFFF;

#[async_trait]
impl CommitLogMarshaller<Event> for EventEnvelopeMarshaller {
    fn entity_type(&self) -> EntityType {
        self.entity_type.clone()
    }

    fn to_compaction_key(&self, entity_id: &EntityId, event: &Event) -> Option<Key> {
        let record_type = match event {
        Event::TemperatureRead { .. } => Some(0),
        Event::Registered { .. } => Some(1),
        };
        record_type.and_then(|record_type| {
            let entity_id = entity_id.parse::<u32>().ok()?;
            Some(record_type << EVENT_TYPE_BIT_SHIFT | entity_id as u64)
        })
    }

    fn to_entity_id(&self, record: &ConsumerRecord) -> Option<EntityId> {
        let entity_id = (record.key & EVENT_ID_BIT_MASK) as u32;
        let mut buffer = itoa::Buffer::new();
        Some(EntityId::from(buffer.format(entity_id)))
    }

    async fn envelope(
        &self,
        entity_id: EntityId,
        record: ConsumerRecord,
    ) -> Option<EventEnvelope<Event>> {
        self.decrypted_envelope(entity_id, record).await
    }

    async fn producer_record(
        &self,
        topic: Topic,
        entity_id: EntityId,
        seq_nr: u64,
        timestamp: DateTime<Utc>,
        event: &Event,
    ) -> Option<ProducerRecord> {
        self.encrypted_producer_record(topic, entity_id, seq_nr, timestamp, event)
            .await
    }
}

#[async_trait]
impl EncryptedCommitLogMarshaller<Event> for EventEnvelopeMarshaller {
    type SecretStore = FileSecretStore;

    fn secret_store(&self) -> &Self::SecretStore {
        &self.secret_store
    }

    fn secret_path(&self, _entity_id: &EntityId) -> Arc<str> {
        self.events_key_secret_path.clone()
    }
}

...

        EventEnvelopeMarshaller {
            entity_type: EntityType::from(ENTITY_TYPE),
            events_key_secret_path: Arc::from(events_key_secret_path),
        secret_store,
        },

Fixes #84 Fixes #91

huntc commented 1 year ago

Would be good with one option without encryption as well, especially for demo/samples to get rid of the step having to set up a secret.

I really think that getting people into the practice of using encryption is important. But perhaps we should provide a NoopSecretStore...