milestone: add runtime template state and dlq/retry broker topology
This commit is contained in:
@@ -21,7 +21,9 @@ use lapin::{
|
||||
BasicProperties,
|
||||
};
|
||||
use rustybeds::brokers;
|
||||
use rustybeds::brokers::payload::ENVELOPE_VERSION;
|
||||
use rustybeds::services::amqp::{AmqpConnection, EXCHANGE_NAME};
|
||||
use rustybeds::template_registry::{RuntimeTemplateRegistry, load_runtime_rec_templates};
|
||||
|
||||
/// Attempts to connect to the test broker. Returns None if unreachable so
|
||||
/// tests can skip rather than fail when RabbitMQ is not running locally.
|
||||
@@ -77,12 +79,20 @@ async fn ping_round_trip(channel: &lapin::Channel, routing_key: &str, expected_b
|
||||
.with_reply_to(reply_queue.clone().into())
|
||||
.with_correlation_id(correlation_id.clone().into());
|
||||
|
||||
let body = serde_json::json!({
|
||||
"version": ENVELOPE_VERSION,
|
||||
"op": "ping",
|
||||
"template": "Logger",
|
||||
"correlation_id": correlation_id,
|
||||
"payload": {},
|
||||
});
|
||||
|
||||
channel
|
||||
.basic_publish(
|
||||
EXCHANGE_NAME,
|
||||
routing_key,
|
||||
BasicPublishOptions::default(),
|
||||
b"{}",
|
||||
&serde_json::to_vec(&body).expect("failed to encode ping envelope"),
|
||||
props,
|
||||
)
|
||||
.await
|
||||
@@ -99,8 +109,10 @@ async fn ping_round_trip(channel: &lapin::Channel, routing_key: &str, expected_b
|
||||
let payload: serde_json::Value =
|
||||
serde_json::from_slice(&delivery.data).expect("reply payload is not valid JSON");
|
||||
|
||||
assert_eq!(payload["version"], ENVELOPE_VERSION);
|
||||
assert_eq!(payload["status"], "ok");
|
||||
assert_eq!(payload["broker"], expected_broker);
|
||||
assert_eq!(payload["op"], "ping");
|
||||
assert_eq!(payload["payload"]["broker"], expected_broker);
|
||||
|
||||
if let Some(cid) = delivery.properties.correlation_id().as_ref() {
|
||||
assert_eq!(cid.as_str(), correlation_id);
|
||||
@@ -207,12 +219,20 @@ async fn r_and_w_brokers_process_ping_events() {
|
||||
.await
|
||||
.expect("exchange declaration failed");
|
||||
|
||||
let mut handles = brokers::spawn_r_broker_pool(Arc::clone(&conn), &cfg.broker_services)
|
||||
let template_registry = std::sync::Arc::new(RuntimeTemplateRegistry::from_templates(
|
||||
load_runtime_rec_templates("templates").expect("template load failed"),
|
||||
));
|
||||
|
||||
let mut handles = brokers::spawn_r_broker_pool(
|
||||
Arc::clone(&conn),
|
||||
&cfg.broker_services,
|
||||
std::sync::Arc::clone(&template_registry),
|
||||
)
|
||||
.await
|
||||
.expect("rBroker pool failed to start");
|
||||
|
||||
handles.extend(
|
||||
brokers::spawn_w_broker_pool(Arc::clone(&conn), &cfg.broker_services)
|
||||
brokers::spawn_w_broker_pool(Arc::clone(&conn), &cfg.broker_services, std::sync::Arc::clone(&template_registry))
|
||||
.await
|
||||
.expect("wBroker pool failed to start"),
|
||||
);
|
||||
@@ -254,12 +274,20 @@ async fn logger_write_then_fetch_round_trip() {
|
||||
.await
|
||||
.expect("exchange declaration failed");
|
||||
|
||||
let mut handles = brokers::spawn_r_broker_pool(Arc::clone(&conn), &cfg.broker_services)
|
||||
let template_registry = std::sync::Arc::new(RuntimeTemplateRegistry::from_templates(
|
||||
load_runtime_rec_templates("templates").expect("template load failed"),
|
||||
));
|
||||
|
||||
let mut handles = brokers::spawn_r_broker_pool(
|
||||
Arc::clone(&conn),
|
||||
&cfg.broker_services,
|
||||
std::sync::Arc::clone(&template_registry),
|
||||
)
|
||||
.await
|
||||
.expect("rBroker pool failed to start");
|
||||
|
||||
handles.extend(
|
||||
brokers::spawn_w_broker_pool(Arc::clone(&conn), &cfg.broker_services)
|
||||
brokers::spawn_w_broker_pool(Arc::clone(&conn), &cfg.broker_services, std::sync::Arc::clone(&template_registry))
|
||||
.await
|
||||
.expect("wBroker pool failed to start"),
|
||||
);
|
||||
@@ -270,8 +298,11 @@ async fn logger_write_then_fetch_round_trip() {
|
||||
.expect("failed to create test channel");
|
||||
|
||||
let write_request = serde_json::json!({
|
||||
"version": ENVELOPE_VERSION,
|
||||
"op": "write",
|
||||
"template": "Logger",
|
||||
"data": {
|
||||
"correlation_id": "logger-write-1",
|
||||
"payload": {
|
||||
"message_log": "poc-log-message",
|
||||
"level_log": "info",
|
||||
"service_log": "app_server"
|
||||
@@ -280,20 +311,27 @@ async fn logger_write_then_fetch_round_trip() {
|
||||
|
||||
let write_reply = request_reply_json(&test_channel, "rec.write", "write", write_request).await;
|
||||
assert_eq!(write_reply["status"], "ok");
|
||||
assert_eq!(write_reply["code"], "LOGGER_WRITE");
|
||||
assert_eq!(write_reply["version"], ENVELOPE_VERSION);
|
||||
assert_eq!(write_reply["op"], "write");
|
||||
assert_eq!(write_reply["payload"]["code"], "LOGGER_WRITE");
|
||||
|
||||
let fetch_request = serde_json::json!({
|
||||
"version": ENVELOPE_VERSION,
|
||||
"op": "fetch",
|
||||
"template": "Logger",
|
||||
"data": {
|
||||
"correlation_id": "logger-fetch-1",
|
||||
"payload": {
|
||||
"limit": 10
|
||||
}
|
||||
});
|
||||
|
||||
let fetch_reply = request_reply_json(&test_channel, "rec.read", "fetch", fetch_request).await;
|
||||
assert_eq!(fetch_reply["status"], "ok");
|
||||
assert_eq!(fetch_reply["code"], "LOGGER_FETCH");
|
||||
assert_eq!(fetch_reply["version"], ENVELOPE_VERSION);
|
||||
assert_eq!(fetch_reply["op"], "fetch");
|
||||
assert_eq!(fetch_reply["payload"]["code"], "LOGGER_FETCH");
|
||||
|
||||
let logs = fetch_reply["logs"].as_array().expect("logs must be an array");
|
||||
let logs = fetch_reply["payload"]["logs"].as_array().expect("logs must be an array");
|
||||
assert!(
|
||||
logs.iter().any(|v| v["message_log"] == "poc-log-message"),
|
||||
"fetched logs should include the message just written"
|
||||
|
||||
Reference in New Issue
Block a user