liminal-server 0.28.2

Standalone server for the liminal messaging bus
Documentation
//! The policy's configured wire goes through the existing admitted dialer.

use super::{Backend, Deadline, Facts, OpenError, Packet, Path};
use liminal_server::config::types::{MachineConfig, OutboundLinkConfig};
use liminal_server::link::LinkHost;
use liminal_server::link_carrier::{Carrier, CarrierReceive, LinkCarrier};
use liminal_server::link_dial::{DialedLink, LinkDialOutcome, LinkDialer};
use liminal_server::link_handshake::NOISE_OVERHEAD;
use std::sync::{Arc, Mutex};

pub use crate::support::federation;

fn named(error: impl std::fmt::Display) -> OpenError {
    OpenError(error.to_string())
}

#[derive(Debug)]
pub struct WireBackend {
    host: Arc<LinkHost>,
    machine: MachineConfig,
    facts: Arc<Mutex<Facts>>,
}

impl WireBackend {
    pub fn new(fixture: &federation::Federation, facts: Arc<Mutex<Facts>>) -> Self {
        Self {
            host: Arc::clone(&fixture.exporter.host),
            machine: fixture.exporter.config.clone(),
            facts,
        }
    }
}

#[derive(Debug)]
struct WirePath(Box<DialedLink>);
impl Path for WirePath {
    fn carrier(&self) -> Carrier {
        Carrier::Wire
    }
    fn relay_device(&self) -> Option<String> {
        None
    }
    fn prepare(&mut self, subject: &str, plain: &[u8]) -> Result<Packet, OpenError> {
        let counter = self.0.transport.sending_nonce();
        let mut bytes = vec![0; plain.len() + NOISE_OVERHEAD];
        let length = self.0.transport.seal(plain, &mut bytes).map_err(named)?;
        bytes.truncate(length);
        Ok(Packet {
            subject: subject.to_owned(),
            counter,
            bytes,
            deadline: None,
        })
    }
    fn transmit(&mut self, packet: &Packet) -> Result<(), OpenError> {
        self.0
            .carrier
            .send(&packet.subject, &packet.bytes)
            .map_err(named)
    }
    fn receipt(&mut self, _counter: u64, bound: Option<Deadline>) -> Result<bool, OpenError> {
        assert_eq!(bound, None);
        match self.0.carrier.receive().map_err(named)? {
            CarrierReceive::Acknowledged { .. } => Ok(true),
            answer => Err(OpenError(format!("unexpected_wire_answer: {answer:?}"))),
        }
    }
}

impl Backend for WireBackend {
    fn wire(
        &mut self,
        config: &OutboundLinkConfig,
        address: &str,
    ) -> Result<Box<dyn Path>, OpenError> {
        self.facts
            .lock()
            .map_err(named)?
            .calls
            .push(address.to_owned());
        let mut entry = config.clone();
        entry.peer_address = Some(address.to_owned());
        match LinkDialer::new(&self.host, &self.machine)
            .open(&entry)
            .map_err(named)?
        {
            LinkDialOutcome::Opened(link) => Ok(Box::new(WirePath(link))),
            answer => Err(OpenError(format!("wire_open_did_not_key: {answer:?}"))),
        }
    }
    fn lookup(&mut self, _config: &OutboundLinkConfig) -> Result<Vec<String>, OpenError> {
        Err(OpenError("unexpected_broker_lookup".to_owned()))
    }
    fn punch(&mut self, _config: &OutboundLinkConfig) -> Result<Box<dyn Path>, OpenError> {
        Err(OpenError("unexpected_punch".to_owned()))
    }
    fn relay(&mut self, _config: &OutboundLinkConfig) -> Result<Box<dyn Path>, OpenError> {
        Err(OpenError("unexpected_relay".to_owned()))
    }
    fn repunch(
        &mut self,
        _config: &OutboundLinkConfig,
        _path: &mut dyn Path,
    ) -> Result<(), OpenError> {
        Err(OpenError("unexpected_repunch".to_owned()))
    }
    fn topology(
        &mut self,
        carrier: Option<Carrier>,
        relay: Option<String>,
        refusal: Option<&str>,
    ) -> Result<(), OpenError> {
        self.facts.lock().map_err(named)?.topology.push((
            carrier,
            relay,
            refusal.map(str::to_owned),
        ));
        Ok(())
    }
}