use std::net::SocketAddr;
use rocketmq_model::common::mix_all;
use rocketmq_protocol::protocol::remoting_command::RemotingCommand;
use rocketmq_transport::api::RPCHook;
use crate::base::client_config::ClientConfig;
pub struct NamespaceRpcHook {
client_config: ClientConfig,
}
impl NamespaceRpcHook {
pub fn new(client_config: ClientConfig) -> Self {
Self { client_config }
}
pub fn client_config(&self) -> &ClientConfig {
&self.client_config
}
}
impl RPCHook for NamespaceRpcHook {
fn do_before_request(
&self,
_remote_addr: SocketAddr,
request: &mut RemotingCommand,
) -> Result<(), rocketmq_error::SharedError> {
if let Some(namespace_v2) = self.client_config.get_namespace_v2() {
request.ensure_ext_fields_initialized();
request.add_ext_field(mix_all::RPC_REQUEST_HEADER_NAMESPACED_FIELD, "true");
request.add_ext_field(mix_all::RPC_REQUEST_HEADER_NAMESPACE_FIELD, namespace_v2.as_str());
}
Ok(())
}
fn do_after_response(
&self,
_remote_addr: SocketAddr,
_request: &RemotingCommand,
_response: &mut RemotingCommand,
) -> Result<(), rocketmq_error::SharedError> {
Ok(())
}
}
#[cfg(test)]
mod tests {
use std::net::SocketAddr;
use cheetah_string::CheetahString;
use rocketmq_protocol::protocol::remoting_command::RemotingCommand;
use rocketmq_transport::api::RPCHook;
use super::*;
#[test]
fn test_namespace_rpc_hook_adds_headers_when_namespace_configured() {
let mut config = ClientConfig::default();
config.set_namespace_v2(CheetahString::from_static_str("test-namespace"));
let hook = NamespaceRpcHook::new(config);
let mut request = RemotingCommand::create_remoting_command(1);
let addr: SocketAddr = "127.0.0.1:8080".parse().unwrap();
hook.do_before_request(addr, &mut request).unwrap();
assert_eq!(
request
.ext_fields()
.unwrap()
.get(mix_all::RPC_REQUEST_HEADER_NAMESPACED_FIELD),
Some(&CheetahString::from_static_str("true"))
);
assert_eq!(
request
.ext_fields()
.unwrap()
.get(mix_all::RPC_REQUEST_HEADER_NAMESPACE_FIELD),
Some(&CheetahString::from_static_str("test-namespace"))
);
}
#[test]
fn test_namespace_rpc_hook_no_headers_when_namespace_not_configured() {
let config = ClientConfig::default();
let hook = NamespaceRpcHook::new(config);
let mut request = RemotingCommand::create_remoting_command(1);
let addr: SocketAddr = "127.0.0.1:8080".parse().unwrap();
hook.do_before_request(addr, &mut request).unwrap();
assert_eq!(request.ext_fields(), None);
}
#[test]
fn test_do_after_response_does_nothing() {
let config = ClientConfig::default();
let hook = NamespaceRpcHook::new(config);
let request = RemotingCommand::create_remoting_command(1);
let mut response = RemotingCommand::create_success_response_command();
let addr: SocketAddr = "127.0.0.1:8080".parse().unwrap();
let result = hook.do_after_response(addr, &request, &mut response);
assert!(result.is_ok());
}
#[test]
fn test_client_config_accessor() {
let mut config = ClientConfig::default();
config.set_namespace_v2(CheetahString::from_static_str("test-namespace"));
let hook = NamespaceRpcHook::new(config.clone());
assert_eq!(
hook.client_config().get_namespace_v2(),
Some(&CheetahString::from_static_str("test-namespace"))
);
}
#[test]
fn test_ensure_ext_fields_preserves_existing_data() {
let mut config = ClientConfig::default();
config.set_namespace_v2(CheetahString::from_static_str("test-ns"));
let hook = NamespaceRpcHook::new(config);
let mut request = RemotingCommand::create_remoting_command(100);
let original_opaque = request.opaque();
request.ensure_ext_fields_initialized();
request.add_ext_field("existing-key", "existing-value");
let addr: SocketAddr = "127.0.0.1:8080".parse().unwrap();
hook.do_before_request(addr, &mut request).unwrap();
assert_eq!(request.opaque(), original_opaque);
assert_eq!(
request
.ext_fields()
.unwrap()
.get(&CheetahString::from_static_str("existing-key")),
Some(&CheetahString::from_static_str("existing-value"))
);
assert_eq!(
request
.ext_fields()
.unwrap()
.get(mix_all::RPC_REQUEST_HEADER_NAMESPACED_FIELD),
Some(&CheetahString::from_static_str("true"))
);
assert_eq!(
request
.ext_fields()
.unwrap()
.get(mix_all::RPC_REQUEST_HEADER_NAMESPACE_FIELD),
Some(&CheetahString::from_static_str("test-ns"))
);
}
}