mod bus;
mod deliveries;
mod route;
mod router;
mod seek;
use std::sync::Arc;
use url::Url;
use crate::error::PulsarError;
use crate::in_process::router::Membership;
use crate::subscriber::PulsarSubscriber;
use crate::subscription::PulsarSubscription;
pub(crate) use bus::Bus;
pub(crate) use deliveries::{Queued, Settlement};
pub(crate) use route::{Route, Subscriptions};
pub(crate) use router::{AddressRouter, ConsumerId, Delivery};
pub(crate) use seek::LogSeeker;
pub(crate) fn check_url(url: &str) -> Result<(), PulsarError> {
let parsed = Url::parse(url).map_err(|err| {
PulsarError::Connect(Box::from(format!(
"the service URL is not one the client can connect with: {err}"
)))
})?;
if !matches!(parsed.scheme(), "pulsar" | "pulsar+ssl") {
return Err(PulsarError::Connect(Box::from(format!(
"the service URL's scheme {:?} is not one the client dials: pulsar or pulsar+ssl",
parsed.scheme()
))));
}
if parsed.host_str().is_none() {
return Err(PulsarError::Connect(Box::from(
"the service URL names no host for the client to connect to",
)));
}
Ok(())
}
pub(crate) fn subscribe(
bus: &Arc<Bus>,
descriptor: PulsarSubscription,
route: Route,
) -> Result<(PulsarSubscriber, ConsumerId), PulsarError> {
let display = descriptor.display_topic();
let dead_letter = descriptor.dead_letter_policy()?;
let membership = Membership::new(descriptor.subscription, descriptor.sub_type);
let id = bus
.router()
.subscribe(route.clone(), membership, dead_letter, bus.coordinator())
.map_err(|held| PulsarError::Subscribe {
topic: display.clone(),
source: Box::new(held),
})?;
let subscriber = PulsarSubscriber::in_process(
display,
Queued::new(Arc::clone(bus), id, route, descriptor.ack_timeout),
descriptor.batch_wait,
);
Ok((subscriber, id))
}
#[cfg(test)]
mod url_tests {
use super::check_url;
#[test]
fn a_url_the_client_does_not_dial_is_refused() {
assert!(check_url("pulsar://broker:6650").is_ok());
assert!(check_url("pulsar+ssl://broker:6651").is_ok());
for refused in [
"http://broker:6650",
"pulsar://one:6650,two:6650",
"broker:6650",
] {
assert!(check_url(refused).is_err(), "{refused}");
}
}
}