use std::net::IpAddr;
use std::net::Ipv4Addr;
use std::net::SocketAddr;
use std::sync::Arc;
use rocketmq_runtime::TaskGroup;
use crate::base::pending_request_table::PendingRequestTable;
use crate::error_helpers::TransportStage;
use crate::net::channel::Channel;
use crate::net::channel::ChannelInner;
use crate::session_view::SessionId;
mod embedded;
pub use embedded::EmbeddedRequestHarness;
pub use crate::client::connect_target_with_config_options_and_telemetry;
pub use crate::client::connect_with_config;
pub use crate::client::connect_with_config_and_telemetry;
pub use crate::client::connect_with_config_options_and_telemetry;
pub use crate::codec::remoting_command_codec::RemotingCommandCodec;
pub use crate::connection::transport_io_snapshot;
pub use crate::connection::Connection;
pub use crate::server::run_connected_session;
pub use crate::server::run_connected_session_with_io_policy;
pub use crate::server::ConnectionHandler;
pub use crate::server::SessionHandle;
pub use crate::server::SessionIoPolicy;
pub use crate::server::SessionProcessor;
pub use crate::server::SessionTransportServer;
pub use crate::server::SessionTransportServerConfig;
pub use crate::server::TransportListener;
#[cfg(not(feature = "tls"))]
pub use crate::tls::tls_disabled_error;
pub use crate::write_strategy::FrameWriteMode;
pub use crate::write_strategy::FrameWriter;
pub use crate::writer_runtime::MicroBatchConfig;
pub use crate::writer_runtime::WriterQueueConfig;
#[must_use]
pub fn session_id_for_test(owner_id: u64) -> SessionId {
assert!(
!matches!(owner_id, 0 | u64::MAX),
"test session owner must use a production-valid identity"
);
SessionId::from_session_owner(owner_id)
}
pub struct LocalChannelHarness {
channel: Channel,
_peer: Connection,
}
impl LocalChannelHarness {
pub async fn new(parent_task_group: TaskGroup) -> Result<Self, rocketmq_error::SharedError> {
let listener = tokio::net::TcpListener::bind("127.0.0.1:0")
.await
.map_err(|source| crate::error_helpers::connection_failed(TransportStage::Connect, source))?;
let server_addr = listener
.local_addr()
.map_err(|source| crate::error_helpers::connection_failed(TransportStage::Connect, source))?;
let (client_stream, (server_stream, _)) =
tokio::try_join!(tokio::net::TcpStream::connect(server_addr), listener.accept())
.map_err(|source| crate::error_helpers::connection_failed(TransportStage::Connect, source))?;
let local_address = server_stream
.local_addr()
.map_err(|source| crate::error_helpers::connection_failed(TransportStage::Connect, source))?;
let remote_address = server_stream
.peer_addr()
.map_err(|source| crate::error_helpers::connection_failed(TransportStage::Connect, source))?;
let client_peer = client_stream
.peer_addr()
.map_err(|source| crate::error_helpers::connection_failed(TransportStage::Connect, source))?;
let client_local = client_stream
.local_addr()
.map_err(|source| crate::error_helpers::connection_failed(TransportStage::Connect, source))?;
debug_assert_eq!(local_address, client_peer);
debug_assert_eq!(remote_address, client_local);
let channel = TestChannelBuilder::new(Connection::new(server_stream), parent_task_group)
.addresses(local_address, remote_address)
.build()?;
Ok(Self {
channel,
_peer: Connection::new(client_stream),
})
}
#[must_use]
pub fn channel(&self) -> Channel {
self.channel.clone()
}
#[must_use]
pub fn local_address(&self) -> SocketAddr {
self.channel.local_address()
}
#[must_use]
pub fn remote_address(&self) -> SocketAddr {
self.channel.remote_address()
}
}
pub struct TestChannelBuilder {
connection: Connection,
task_group: TaskGroup,
local_address: SocketAddr,
remote_address: SocketAddr,
}
impl TestChannelBuilder {
#[must_use]
pub fn new(connection: Connection, task_group: TaskGroup) -> Self {
let unspecified = SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 0);
Self {
connection,
task_group,
local_address: unspecified,
remote_address: unspecified,
}
}
#[must_use]
pub fn addresses(mut self, local_address: SocketAddr, remote_address: SocketAddr) -> Self {
self.local_address = local_address;
self.remote_address = remote_address;
self
}
#[must_use]
pub fn write_preflight_barrier(
mut self,
entered: Arc<tokio::sync::Notify>,
release: Arc<tokio::sync::Notify>,
) -> Self {
self.connection
.set_write_preflight_barrier(crate::write_strategy::WritePreflightBarrier::new(entered, release));
self
}
pub fn build(self) -> Result<Channel, rocketmq_error::SharedError> {
let inner =
ChannelInner::try_new_with_pending_requests(self.connection, PendingRequestTable::new(), self.task_group)?;
Ok(Channel::new(Arc::new(inner), self.local_address, self.remote_address))
}
}