This commit is contained in:
nora 2022-03-04 22:15:19 +01:00
parent 93ce632b5d
commit 4346db648f
24 changed files with 224 additions and 209 deletions

3
.rustfmt.toml Normal file
View file

@ -0,0 +1,3 @@
reorder_imports = true
imports_granularity = "Crate"
newline_style = "Unix"

17
Cargo.lock generated
View file

@ -19,6 +19,7 @@ dependencies = [
"amqp_dashboard", "amqp_dashboard",
"amqp_transport", "amqp_transport",
"anyhow", "anyhow",
"clap 3.1.5",
"tokio", "tokio",
"tracing", "tracing",
"tracing-subscriber", "tracing-subscriber",
@ -223,9 +224,9 @@ dependencies = [
[[package]] [[package]]
name = "clap" name = "clap"
version = "3.1.1" version = "3.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d76c22c9b9b215eeb8d016ad3a90417bd13cb24cf8142756e6472445876cab7" checksum = "ced1892c55c910c1219e98d6fc8d71f6bddba7905866ce740066d8bfea859312"
dependencies = [ dependencies = [
"atty", "atty",
"bitflags", "bitflags",
@ -235,14 +236,14 @@ dependencies = [
"os_str_bytes", "os_str_bytes",
"strsim", "strsim",
"termcolor", "termcolor",
"textwrap 0.14.2", "textwrap 0.15.0",
] ]
[[package]] [[package]]
name = "clap_derive" name = "clap_derive"
version = "3.1.0" version = "3.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fd1122e63869df2cb309f449da1ad54a7c6dfeb7c7e6ccd8e0825d9eb93bb72" checksum = "da95d038ede1a964ce99f49cbe27a7fb538d1da595e4b4f70b8c8f338d17bf16"
dependencies = [ dependencies = [
"heck", "heck",
"proc-macro-error", "proc-macro-error",
@ -1138,9 +1139,9 @@ dependencies = [
[[package]] [[package]]
name = "textwrap" name = "textwrap"
version = "0.14.2" version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
[[package]] [[package]]
name = "thiserror" name = "thiserror"
@ -1562,7 +1563,7 @@ name = "xtask"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"clap 3.1.1", "clap 3.1.5",
"heck", "heck",
"itertools", "itertools",
"strong-xml", "strong-xml",

View file

@ -13,6 +13,7 @@ anyhow = "1.0.53"
amqp_core = { path = "./amqp_core" } amqp_core = { path = "./amqp_core" }
amqp_dashboard = { path = "./amqp_dashboard" } amqp_dashboard = { path = "./amqp_dashboard" }
amqp_transport = { path = "./amqp_transport" } amqp_transport = { path = "./amqp_transport" }
clap = { version = "3.1.5", features = ["derive"] }
tokio = { version = "1.16.1", features = ["full"] } tokio = { version = "1.16.1", features = ["full"] }
tracing = "0.1.30" tracing = "0.1.30"
tracing-subscriber = { version = "0.3.8", features = ["env-filter"] } tracing-subscriber = { version = "0.3.8", features = ["env-filter"] }

View file

@ -1,12 +1,12 @@
use crate::methods::Method; use crate::{methods, methods::Method, newtype_id, GlobalData, Queue};
use crate::{methods, newtype_id, GlobalData, Handle, Queue};
use bytes::Bytes; use bytes::Bytes;
use parking_lot::Mutex;
use smallvec::SmallVec; use smallvec::SmallVec;
use std::collections::HashMap; use std::{
use std::fmt::{Display, Formatter}; collections::HashMap,
use std::net::SocketAddr; fmt::{Display, Formatter},
use std::sync::Arc; net::SocketAddr,
sync::Arc,
};
use tokio::sync::mpsc; use tokio::sync::mpsc;
newtype_id!(pub ConnectionId); newtype_id!(pub ConnectionId);
@ -43,16 +43,14 @@ impl Display for ChannelNum {
} }
} }
pub type ConnectionHandle = Handle<Connection>;
#[derive(Debug)] #[derive(Debug)]
pub struct Connection { pub struct Connection {
pub id: ConnectionId, pub id: ConnectionId,
pub peer_addr: SocketAddr, pub peer_addr: SocketAddr,
pub global_data: GlobalData, pub global_data: GlobalData,
pub channels: HashMap<ChannelNum, ChannelHandle>, pub channels: HashMap<ChannelNum, Channel>,
pub exclusive_queues: Vec<Queue>, pub exclusive_queues: Vec<Queue>,
_method_queue: MethodSender, _events: ConEventSender,
} }
#[derive(Debug)] #[derive(Debug)]
@ -61,25 +59,25 @@ pub enum QueuedMethod {
WithContent(Method, ContentHeader, SmallVec<[Bytes; 1]>), WithContent(Method, ContentHeader, SmallVec<[Bytes; 1]>),
} }
pub type MethodSender = mpsc::Sender<(ChannelNum, QueuedMethod)>; pub type ConEventSender = mpsc::Sender<(ChannelNum, QueuedMethod)>;
pub type MethodReceiver = mpsc::Receiver<(ChannelNum, QueuedMethod)>; pub type ConEventReceiver = mpsc::Receiver<(ChannelNum, QueuedMethod)>;
impl Connection { impl Connection {
#[must_use] #[must_use]
pub fn new_handle( pub fn new(
id: ConnectionId, id: ConnectionId,
peer_addr: SocketAddr, peer_addr: SocketAddr,
global_data: GlobalData, global_data: GlobalData,
method_queue: MethodSender, method_queue: ConEventSender,
) -> ConnectionHandle { ) -> Arc<Connection> {
Arc::new(Mutex::new(Self { Arc::new(Self {
id, id,
peer_addr, peer_addr,
global_data, global_data,
channels: HashMap::new(), channels: HashMap::new(),
exclusive_queues: vec![], exclusive_queues: vec![],
_method_queue: method_queue, _events: method_queue,
})) })
} }
pub fn close(&self) { pub fn close(&self) {
@ -88,33 +86,31 @@ impl Connection {
} }
} }
pub type ChannelHandle = Handle<Channel>;
#[derive(Debug)] #[derive(Debug)]
pub struct Channel { pub struct Channel {
pub id: ChannelId, pub id: ChannelId,
pub num: ChannelNum, pub num: ChannelNum,
pub connection: ConnectionHandle, pub connection: Connection,
pub global_data: GlobalData, pub global_data: GlobalData,
method_queue: MethodSender, method_queue: ConEventSender,
} }
impl Channel { impl Channel {
#[must_use] #[must_use]
pub fn new_handle( pub fn new(
id: ChannelId, id: ChannelId,
num: ChannelNum, num: ChannelNum,
connection: ConnectionHandle, connection: Connection,
global_data: GlobalData, global_data: GlobalData,
method_queue: MethodSender, method_queue: ConEventSender,
) -> ChannelHandle { ) -> Arc<Channel> {
Arc::new(Mutex::new(Self { Arc::new(Self {
id, id,
num, num,
connection, connection,
global_data, global_data,
method_queue, method_queue,
})) })
} }
pub fn close(&self) { pub fn close(&self) {
@ -130,6 +126,7 @@ impl Channel {
} }
} }
/// A content frame header.
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct ContentHeader { pub struct ContentHeader {
pub class_id: u16, pub class_id: u16,

View file

@ -1,4 +1,4 @@
use crate::{newtype_id, ChannelHandle}; use crate::{newtype_id, Channel};
newtype_id!( newtype_id!(
pub ConsumerId pub ConsumerId
@ -8,5 +8,5 @@ newtype_id!(
pub struct Consumer { pub struct Consumer {
pub id: ConsumerId, pub id: ConsumerId,
pub tag: String, pub tag: String,
pub channel: ChannelHandle, pub channel: Channel,
} }

View file

@ -8,16 +8,15 @@ pub mod message;
pub mod methods; pub mod methods;
pub mod queue; pub mod queue;
use crate::connection::{ChannelHandle, ConnectionHandle}; use crate::{
use crate::queue::{Queue, QueueName}; connection::{Channel, Connection},
queue::{Queue, QueueName},
};
use connection::{ChannelId, ConnectionId}; use connection::{ChannelId, ConnectionId};
use parking_lot::Mutex; use parking_lot::Mutex;
use std::collections::HashMap; use std::{collections::HashMap, sync::Arc};
use std::sync::Arc;
use uuid::Uuid; use uuid::Uuid;
type Handle<T> = Arc<Mutex<T>>;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct GlobalData { pub struct GlobalData {
inner: Arc<Mutex<GlobalDataInner>>, inner: Arc<Mutex<GlobalDataInner>>,
@ -44,8 +43,8 @@ impl GlobalData {
#[derive(Debug)] #[derive(Debug)]
pub struct GlobalDataInner { pub struct GlobalDataInner {
pub connections: HashMap<ConnectionId, ConnectionHandle>, pub connections: HashMap<ConnectionId, Connection>,
pub channels: HashMap<ChannelId, ChannelHandle>, pub channels: HashMap<ChannelId, Channel>,
pub queues: HashMap<QueueName, Queue>, pub queues: HashMap<QueueName, Queue>,
/// Todo: This is just for testing and will be removed later! /// Todo: This is just for testing and will be removed later!
pub default_exchange: HashMap<String, Queue>, pub default_exchange: HashMap<String, Queue>,

View file

@ -1,5 +1,4 @@
use crate::connection::ContentHeader; use crate::{connection::ContentHeader, newtype_id};
use crate::newtype_id;
use bytes::Bytes; use bytes::Bytes;
use smallvec::SmallVec; use smallvec::SmallVec;
use std::sync::Arc; use std::sync::Arc;

View file

@ -1,10 +1,9 @@
use crate::consumer::Consumer; use crate::{consumer::Consumer, message::Message, newtype, newtype_id, ChannelId};
use crate::message::Message;
use crate::{newtype, newtype_id, ChannelId};
use parking_lot::Mutex; use parking_lot::Mutex;
use std::borrow::Borrow; use std::{
use std::sync::atomic::AtomicUsize; borrow::Borrow,
use std::sync::Arc; sync::{atomic::AtomicUsize, Arc},
};
pub type Queue = Arc<RawQueue>; pub type Queue = Arc<RawQueue>;

View file

@ -1,10 +1,12 @@
#![warn(rust_2018_idioms)] #![warn(rust_2018_idioms)]
use amqp_core::GlobalData; use amqp_core::GlobalData;
use axum::body::{boxed, Full}; use axum::{
use axum::response::{Html, IntoResponse, Response}; body::{boxed, Full},
use axum::routing::get; response::{Html, IntoResponse, Response},
use axum::{Json, Router}; routing::get,
Json, Router,
};
use serde::Serialize; use serde::Serialize;
use tracing::info; use tracing::info;

View file

@ -1,13 +1,15 @@
use crate::Result; use crate::Result;
use amqp_core::amqp_todo; use amqp_core::{
use amqp_core::connection::ChannelHandle; amqp_todo,
use amqp_core::consumer::{Consumer, ConsumerId}; connection::Channel,
use amqp_core::error::{ChannelException}; consumer::{Consumer, ConsumerId},
use amqp_core::methods::{BasicConsume, BasicConsumeOk, Method}; error::ChannelException,
methods::{BasicConsume, BasicConsumeOk, Method},
};
use std::sync::Arc; use std::sync::Arc;
use tracing::info; use tracing::info;
pub fn consume(channel_handle: ChannelHandle, basic_consume: BasicConsume) -> Result<Method> { pub fn consume(channel_handle: Channel, basic_consume: BasicConsume) -> Result<Method> {
let BasicConsume { let BasicConsume {
queue: queue_name, queue: queue_name,
consumer_tag, consumer_tag,

View file

@ -3,20 +3,18 @@ mod publish;
mod queue; mod queue;
use crate::Result; use crate::Result;
use amqp_core::amqp_todo; use amqp_core::{amqp_todo, connection::Channel, message::Message, methods::Method};
use amqp_core::connection::ChannelHandle; use std::sync::Arc;
use amqp_core::message::Message;
use amqp_core::methods::Method;
use tracing::{error, info}; use tracing::{error, info};
pub async fn handle_basic_publish(channel_handle: ChannelHandle, message: Message) { pub async fn handle_basic_publish(channel_handle: Arc<Channel>, message: Message) {
match publish::publish(channel_handle, message).await { match publish::publish(channel_handle, message).await {
Ok(()) => {} Ok(()) => {}
Err(err) => error!(%err, "publish error occurred"), Err(err) => error!(%err, "publish error occurred"),
} }
} }
pub async fn handle_method(channel_handle: ChannelHandle, method: Method) -> Result<Method> { pub async fn handle_method(channel_handle: Arc<Channel>, method: Method) -> Result<Method> {
info!(?method, "Handling method"); info!(?method, "Handling method");
let response = match method { let response = match method {

View file

@ -1,12 +1,14 @@
use crate::Result; use crate::Result;
use amqp_core::amqp_todo; use amqp_core::{
use amqp_core::connection::{ChannelHandle, QueuedMethod}; amqp_todo,
use amqp_core::error::ChannelException; connection::{Channel, QueuedMethod},
use amqp_core::message::Message; error::ChannelException,
use amqp_core::methods::{BasicPublish, Method}; message::Message,
methods::{BasicPublish, Method},
};
use tracing::info; use tracing::info;
pub async fn publish(channel_handle: ChannelHandle, message: Message) -> Result<()> { pub async fn publish(channel_handle: Arc<Channel>, message: Message) -> Result<()> {
info!(?message, "Publishing message"); info!(?message, "Publishing message");
let global_data = channel_handle.lock().global_data.clone(); let global_data = channel_handle.lock().global_data.clone();

View file

@ -1,16 +1,15 @@
use amqp_core::connection::ChannelHandle;
use amqp_core::methods::{Method, QueueBind, QueueDeclare, QueueDeclareOk};
use amqp_core::queue::{QueueDeletion, QueueId, QueueName, RawQueue};
use amqp_core::{amqp_todo, GlobalData};
use parking_lot::Mutex;
use std::sync::atomic::AtomicUsize;
use std::sync::Arc;
use crate::Result; use crate::Result;
use amqp_core::{
amqp_todo,
connection::Channel,
methods::{Method, QueueBind, QueueDeclare, QueueDeclareOk},
queue::{QueueDeletion, QueueId, QueueName, RawQueue},
GlobalData,
};
use parking_lot::Mutex;
use std::sync::{atomic::AtomicUsize, Arc};
pub fn declare( pub fn declare(channel_handle: Channel, queue_declare: QueueDeclare) -> Result<Method> {
channel_handle: ChannelHandle,
queue_declare: QueueDeclare,
) -> Result<Method> {
let QueueDeclare { let QueueDeclare {
queue: queue_name, queue: queue_name,
passive, passive,
@ -70,18 +69,11 @@ pub fn declare(
})) }))
} }
pub async fn bind( pub async fn bind(_channel_handle: Channel, _queue_bind: QueueBind) -> Result<Method> {
_channel_handle: ChannelHandle,
_queue_bind: QueueBind,
) -> Result<Method> {
amqp_todo!(); amqp_todo!();
} }
fn bind_queue( fn bind_queue(global_data: GlobalData, _exchange: (), routing_key: Arc<str>) -> Result<()> {
global_data: GlobalData,
_exchange: (),
routing_key: Arc<str>,
) -> Result<()> {
let mut global_data = global_data.lock(); let mut global_data = global_data.lock();
// todo: don't // todo: don't

View file

@ -1,29 +1,34 @@
use crate::error::{ConException, ProtocolError, Result, TransError}; use crate::{
use crate::frame::{parse_content_header, Frame, FrameType}; error::{ConException, ProtocolError, Result, TransError},
use crate::{frame, methods, sasl}; frame,
use amqp_core::connection::{ frame::{parse_content_header, Frame, FrameType},
ChannelHandle, ChannelNum, ConnectionHandle, ConnectionId, ContentHeader, MethodReceiver, methods, sasl,
MethodSender, QueuedMethod,
}; };
use amqp_core::message::{MessageId, RawMessage, RoutingInformation}; use amqp_core::{
use amqp_core::methods::{ amqp_todo,
BasicPublish, ChannelClose, ChannelCloseOk, ChannelOpenOk, ConnectionClose, ConnectionCloseOk, connection::{
ConnectionOpen, ConnectionOpenOk, ConnectionStart, ConnectionStartOk, ConnectionTune, Channel, ChannelNum, ConEventReceiver, ConEventSender, Connection, ConnectionId,
ConnectionTuneOk, FieldValue, Method, Table, ContentHeader, QueuedMethod,
},
message::{MessageId, RawMessage, RoutingInformation},
methods::{
BasicPublish, ChannelClose, ChannelCloseOk, ChannelOpenOk, ConnectionClose,
ConnectionCloseOk, ConnectionOpen, ConnectionOpenOk, ConnectionStart, ConnectionStartOk,
ConnectionTune, ConnectionTuneOk, FieldValue, Method, Table,
},
GlobalData,
}; };
use amqp_core::{amqp_todo, GlobalData};
use anyhow::Context; use anyhow::Context;
use bytes::Bytes; use bytes::Bytes;
use smallvec::SmallVec; use smallvec::SmallVec;
use std::cmp::Ordering; use std::{
use std::collections::HashMap; cmp::Ordering, collections::HashMap, net::SocketAddr, pin::Pin, sync::Arc, time::Duration,
use std::net::SocketAddr; };
use std::pin::Pin; use tokio::{
use std::sync::Arc; io::{AsyncReadExt, AsyncWriteExt},
use std::time::Duration; net::TcpStream,
use tokio::io::{AsyncReadExt, AsyncWriteExt}; select, time,
use tokio::net::TcpStream; };
use tokio::{select, time};
use tracing::{debug, error, info, trace, warn}; use tracing::{debug, error, info, trace, warn};
fn ensure_conn(condition: bool) -> Result<()> { fn ensure_conn(condition: bool) -> Result<()> {
@ -39,16 +44,16 @@ const CHANNEL_MAX: u16 = 0;
const FRAME_SIZE_MAX: u32 = 0; const FRAME_SIZE_MAX: u32 = 0;
const HEARTBEAT_DELAY: u16 = 0; const HEARTBEAT_DELAY: u16 = 0;
const BASIC_CLASS_ID: u16 = 60; const BASIC_CLASS_ID: ChannelNum = ChannelNum::new(60);
pub struct Channel { pub struct TransportChannel {
/// A handle to the global channel representation. Used to remove the channel when it's dropped /// A handle to the global channel representation. Used to remove the channel when it's dropped
handle: ChannelHandle, global_chan: Arc<Channel>,
/// The current status of the channel, whether it has sent a method that expects a body /// The current status of the channel, whether it has sent a method that expects a body
status: ChannelStatus, status: ChannelStatus,
} }
pub struct Connection { pub struct TransportConnection {
id: ConnectionId, id: ConnectionId,
stream: TcpStream, stream: TcpStream,
max_frame_size: usize, max_frame_size: usize,
@ -56,20 +61,19 @@ pub struct Connection {
channel_max: u16, channel_max: u16,
/// When the next heartbeat expires /// When the next heartbeat expires
next_timeout: Pin<Box<time::Sleep>>, next_timeout: Pin<Box<time::Sleep>>,
channels: HashMap<ChannelNum, Channel>, channels: HashMap<ChannelNum, TransportChannel>,
handle: ConnectionHandle, global_con: Arc<Connection>,
global_data: GlobalData, global_data: GlobalData,
method_queue_send: MethodSender, method_queue_send: ConEventSender,
method_queue_recv: MethodReceiver, method_queue_recv: ConEventReceiver,
} }
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(30); const DEFAULT_TIMEOUT: Duration = Duration::from_secs(30);
enum ChannelStatus { enum ChannelStatus {
Default, Default,
/// ClassId // todo: newtype it NeedHeader(ChannelNum, Box<Method>),
NeedHeader(u16, Box<Method>),
NeedsBody(Box<Method>, ContentHeader, SmallVec<[Bytes; 1]>), NeedsBody(Box<Method>, ContentHeader, SmallVec<[Bytes; 1]>),
} }
@ -79,14 +83,14 @@ impl ChannelStatus {
} }
} }
impl Connection { impl TransportConnection {
pub fn new( pub fn new(
id: ConnectionId, id: ConnectionId,
stream: TcpStream, stream: TcpStream,
connection_handle: ConnectionHandle, connection_handle: Arc<GConnection>,
global_data: GlobalData, global_data: GlobalData,
method_queue_send: MethodSender, method_queue_send: ConEventSender,
method_queue_recv: MethodReceiver, method_queue_recv: ConEventReceiver,
) -> Self { ) -> Self {
Self { Self {
id, id,
@ -95,11 +99,11 @@ impl Connection {
heartbeat_delay: HEARTBEAT_DELAY, heartbeat_delay: HEARTBEAT_DELAY,
channel_max: CHANNEL_MAX, channel_max: CHANNEL_MAX,
next_timeout: Box::pin(time::sleep(DEFAULT_TIMEOUT)), next_timeout: Box::pin(time::sleep(DEFAULT_TIMEOUT)),
handle: connection_handle, global_con: connection_handle,
channels: HashMap::with_capacity(4), channels: HashMap::with_capacity(4),
global_data, global_data,
method_queue_send, method_queue_send,
method_queue_recv: method_queue_recv, method_queue_recv,
} }
} }
@ -140,7 +144,7 @@ impl Connection {
Err(err) => error!(%err, "Error during processing of connection"), Err(err) => error!(%err, "Error during processing of connection"),
} }
let connection_handle = self.handle.lock(); let connection_handle = self.global_con.lock();
connection_handle.close(); connection_handle.close();
} }
@ -364,7 +368,7 @@ impl Connection {
.channels .channels
.get(&frame.channel) .get(&frame.channel)
.ok_or(ConException::Todo)? .ok_or(ConException::Todo)?
.handle .global_chan
.clone(); .clone();
// call into amqp_messaging to handle the method // call into amqp_messaging to handle the method
@ -470,7 +474,7 @@ impl Connection {
// Spawn the handler for the publish. The connection task goes back to handling // Spawn the handler for the publish. The connection task goes back to handling
// just the connection. // just the connection.
tokio::spawn(amqp_messaging::methods::handle_basic_publish( tokio::spawn(amqp_messaging::methods::handle_basic_publish(
channel.handle.clone(), channel.global_chan.clone(),
message, message,
)); ));
Ok(()) Ok(())
@ -481,16 +485,16 @@ impl Connection {
async fn channel_open(&mut self, channel_num: ChannelNum) -> Result<()> { async fn channel_open(&mut self, channel_num: ChannelNum) -> Result<()> {
let id = rand::random(); let id = rand::random();
let channel_handle = amqp_core::connection::Channel::new_handle( let channel_handle = amqp_core::connection::c::new_handle(
id, id,
channel_num, channel_num,
self.handle.clone(), self.global_con.clone(),
self.global_data.clone(), self.global_data.clone(),
self.method_queue_send.clone(), self.method_queue_send.clone(),
); );
let channel = Channel { let channel = TransportChannel {
handle: channel_handle.clone(), global_chan: channel_handle.clone(),
status: ChannelStatus::Default, status: ChannelStatus::Default,
}; };
@ -597,15 +601,15 @@ impl Connection {
} }
} }
impl Drop for Connection { impl Drop for TransportConnection {
fn drop(&mut self) { fn drop(&mut self) {
self.handle.lock().close(); self.global_con.lock().close();
} }
} }
impl Drop for Channel { impl Drop for TransportChannel {
fn drop(&mut self) { fn drop(&mut self) {
self.handle.lock().close(); self.global_chan.lock().close();
} }
} }

View file

@ -33,13 +33,19 @@ pub enum FrameType {
} }
mod content_header_parse { mod content_header_parse {
use crate::error::TransError; use crate::{
use crate::methods::parse_helper::{octet, shortstr, table, timestamp}; error::TransError,
use amqp_core::connection::ContentHeader; methods::parse_helper::{octet, shortstr, table, timestamp},
use amqp_core::methods; };
use amqp_core::methods::FieldValue::{FieldTable, ShortShortUInt, ShortString, Timestamp}; use amqp_core::{
use nom::number::complete::{u16, u64}; connection::ContentHeader,
use nom::number::Endianness::Big; methods,
methods::FieldValue::{FieldTable, ShortShortUInt, ShortString, Timestamp},
};
use nom::number::{
complete::{u16, u64},
Endianness::Big,
};
type IResult<'a, T> = nom::IResult<&'a [u8], T, TransError>; type IResult<'a, T> = nom::IResult<&'a [u8], T, TransError>;

View file

@ -10,7 +10,7 @@ mod tests;
// TODO: handle big types // TODO: handle big types
use crate::connection::Connection; use crate::connection::TransportConnection;
use amqp_core::GlobalData; use amqp_core::GlobalData;
use anyhow::Result; use anyhow::Result;
use tokio::net; use tokio::net;
@ -31,7 +31,7 @@ pub async fn do_thing_i_guess(global_data: GlobalData) -> Result<()> {
let (method_send, method_recv) = tokio::sync::mpsc::channel(10); let (method_send, method_recv) = tokio::sync::mpsc::channel(10);
let connection_handle = amqp_core::connection::Connection::new_handle( let connection_handle = amqp_core::connection::ConnectionInner::new_handle(
id, id,
peer_addr, peer_addr,
global_data.clone(), global_data.clone(),
@ -43,7 +43,7 @@ pub async fn do_thing_i_guess(global_data: GlobalData) -> Result<()> {
.connections .connections
.insert(id, connection_handle.clone()); .insert(id, connection_handle.clone());
let connection = Connection::new( let connection = TransportConnection::new(
id, id,
stream, stream,
connection_handle, connection_handle,

View file

@ -2,8 +2,7 @@
// This file has been generated by `xtask/src/codegen`. Do not edit it manually. // This file has been generated by `xtask/src/codegen`. Do not edit it manually.
pub mod parse { pub mod parse {
use crate::error::TransError; use crate::{error::TransError, methods::parse_helper::*};
use crate::methods::parse_helper::*;
use amqp_core::methods::*; use amqp_core::methods::*;
use nom::{branch::alt, bytes::complete::tag}; use nom::{branch::alt, bytes::complete::tag};
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
@ -887,8 +886,7 @@ pub mod parse {
} }
} }
pub mod write { pub mod write {
use crate::error::TransError; use crate::{error::TransError, methods::write_helper::*};
use crate::methods::write_helper::*;
use amqp_core::methods::*; use amqp_core::methods::*;
use std::io::Write; use std::io::Write;

View file

@ -1,6 +1,8 @@
use crate::error::TransError; use crate::error::TransError;
use amqp_core::error::ConException; use amqp_core::{
use amqp_core::methods::{FieldValue, Method, Table}; error::ConException,
methods::{FieldValue, Method, Table},
};
use rand::Rng; use rand::Rng;
mod generated; mod generated;

View file

@ -1,17 +1,22 @@
use crate::error::TransError; use crate::{error::TransError, methods::generated::parse::IResult};
use crate::methods::generated::parse::IResult; use amqp_core::{
use amqp_core::error::{ConException, ProtocolError}; error::{ConException, ProtocolError},
use amqp_core::methods::{ methods::{
Bit, FieldValue, Long, Longlong, Longstr, Octet, Short, Shortstr, Table, TableFieldName, Bit, FieldValue, Long, Longlong, Longstr, Octet, Short, Shortstr, Table, TableFieldName,
Timestamp, Timestamp,
},
};
use nom::{
branch::alt,
bytes::complete::{tag, take},
error::ErrorKind,
multi::{count, many0},
number::{
complete::{f32, f64, i16, i32, i64, i8, u16, u32, u64, u8},
Endianness::Big,
},
Err,
}; };
use nom::branch::alt;
use nom::bytes::complete::{tag, take};
use nom::error::ErrorKind;
use nom::multi::{count, many0};
use nom::number::complete::{f32, f64, i16, i32, i64, i8, u16, u32, u64, u8};
use nom::number::Endianness::Big;
use nom::Err;
impl<T> nom::error::ParseError<T> for TransError { impl<T> nom::error::ParseError<T> for TransError {
fn from_error_kind(_input: T, _kind: ErrorKind) -> Self { fn from_error_kind(_input: T, _kind: ErrorKind) -> Self {

View file

@ -1,5 +1,4 @@
use crate::error::TransError; use crate::{error::TransError, methods::FieldValue};
use crate::methods::FieldValue;
use amqp_core::methods::{Bit, Long, Longlong, Longstr, Octet, Short, Shortstr, Table, Timestamp}; use amqp_core::methods::{Bit, Long, Longlong, Longstr, Octet, Short, Shortstr, Table, Timestamp};
use anyhow::Context; use anyhow::Context;
use std::io::Write; use std::io::Write;

View file

@ -1,7 +1,8 @@
use crate::frame::FrameType; use crate::{frame, frame::FrameType, methods};
use crate::{frame, methods}; use amqp_core::{
use amqp_core::connection::ChannelNum; connection::ChannelNum,
use amqp_core::methods::{ConnectionStart, ConnectionStartOk, FieldValue, Method}; methods::{ConnectionStart, ConnectionStartOk, FieldValue, Method},
};
use std::collections::HashMap; use std::collections::HashMap;
#[tokio::test] #[tokio::test]

View file

@ -1,26 +1,29 @@
#![warn(rust_2018_idioms)] #![warn(rust_2018_idioms)]
use anyhow::Result; use anyhow::Result;
use std::env; use clap::Parser;
use tracing::{info, info_span, Instrument}; use tracing::{info, info_span, Instrument};
/// An AMQP 0-9-1 broker implementation.
#[derive(Parser)]
struct Args {
/// Whether to serve the dashboard on localhost. Port defaults to 3000.
#[clap(short, long)]
dashboard: bool,
/// The log level of the application. Overwrites the `RUST_LOG` env var.
#[clap(long)]
log_level: Option<String>,
}
#[tokio::main] #[tokio::main]
async fn main() -> Result<()> { async fn main() -> Result<()> {
let mut dashboard = false; let args = Args::parse();
for arg in env::args().skip(1) { setup_tracing(&args);
match arg.as_str() {
"--dashboard" => dashboard = true,
"ignore-this-clippy" => eprintln!("yes please"),
_ => {}
}
}
setup_tracing();
let global_data = amqp_core::GlobalData::default(); let global_data = amqp_core::GlobalData::default();
if dashboard { if args.dashboard {
let dashboard_span = info_span!("dashboard"); let dashboard_span = info_span!("dashboard");
tokio::spawn(amqp_dashboard::dashboard(global_data.clone()).instrument(dashboard_span)); tokio::spawn(amqp_dashboard::dashboard(global_data.clone()).instrument(dashboard_span));
} }
@ -28,21 +31,22 @@ async fn main() -> Result<()> {
amqp_transport::do_thing_i_guess(global_data).await amqp_transport::do_thing_i_guess(global_data).await
} }
fn setup_tracing() { fn setup_tracing(args: &Args) {
const DEFAULT_LOG: &str = "hyper=info,debug"; const DEFAULT_LOG: &str = "hyper=info,debug";
let rust_log = std::env::var("RUST_LOG");
let log_filter = args
.log_level
.clone()
.or_else(|| std::env::var("RUST_LOG").ok())
.unwrap_or_else(|| DEFAULT_LOG.to_owned());
tracing_subscriber::fmt() tracing_subscriber::fmt()
.with_level(true) .with_level(true)
.with_timer(tracing_subscriber::fmt::time::time()) .with_timer(tracing_subscriber::fmt::time::time())
.with_ansi(true) .with_ansi(true)
.with_thread_names(true) .with_thread_names(true)
.with_env_filter(rust_log.clone().unwrap_or_else(|_| DEFAULT_LOG.to_string())) .with_env_filter(&log_filter)
.init(); .init();
if let Ok(rust_log) = rust_log { info!(%log_filter, "Using log filter level");
info!(%rust_log, "Using custom log level");
} else {
info!(%DEFAULT_LOG, "Using default log level");
}
} }

View file

@ -6,13 +6,15 @@ mod write;
use anyhow::{bail, Context}; use anyhow::{bail, Context};
use heck::ToUpperCamelCase; use heck::ToUpperCamelCase;
use std::fs; use std::{
use std::fs::File; fs,
use std::io::Write; fs::File,
use std::iter::Peekable; io::Write,
use std::path::{Path, PathBuf}; iter::Peekable,
use std::process::Command; path::{Path, PathBuf},
use std::str::FromStr; process::Command,
str::FromStr,
};
use strong_xml::XmlRead; use strong_xml::XmlRead;
#[derive(Debug, XmlRead)] #[derive(Debug, XmlRead)]

View file

@ -1,7 +1,6 @@
use crate::project_root; use crate::project_root;
use anyhow::{ensure, Context, Result}; use anyhow::{ensure, Context, Result};
use std::path::Path; use std::{path::Path, process::Command};
use std::process::Command;
pub fn main() -> Result<()> { pub fn main() -> Result<()> {
let project_root = project_root(); let project_root = project_root();