mirror of
https://github.com/KumoCorp/kumomta.git
synced 2026-09-21 00:01:12 +00:00
formalize tenant/campaign components of default queue naming
This commit is contained in:
@@ -1,5 +1,22 @@
|
||||
# kumomta
|
||||
|
||||
## Concepts
|
||||
|
||||
### Queuing
|
||||
|
||||
Messages are assigned to a queue upon reception. The system can support
|
||||
arbitrarily named queues but the convention is to construct the queue name from
|
||||
some metadata associated with the message:
|
||||
|
||||
* `tenant` - some kind of sender or customer identifier or identity derived
|
||||
either from the message itself or authentication of the injection session.
|
||||
* `campaign` - a sender-provided label that can be used to logically group a set
|
||||
of related messages, perhaps generated from the same campaign.
|
||||
* destination domain - the site where the email will be routed
|
||||
|
||||
These three pieces of information are combined to produce the name of the queue
|
||||
in the form `campaign:tenant@domain`.
|
||||
|
||||
## Debugging/Tracing
|
||||
|
||||
This will launch the server using the policy defined in [simple_policy.lua](simple_policy.lua):
|
||||
|
||||
@@ -415,12 +415,19 @@ impl SmtpServer {
|
||||
|
||||
ids.push(message.id().to_string());
|
||||
|
||||
let queue_name = match message.get_meta("queue")? {
|
||||
serde_json::Value::String(name) => name.to_string(),
|
||||
serde_json::Value::Null => message.recipient()?.domain().to_string(),
|
||||
value => anyhow::bail!(
|
||||
"expected 'queue' metadata to be a string value, got {value:?}"
|
||||
),
|
||||
let queue_name = match message.get_meta_string("queue")? {
|
||||
Some(name) => name.to_string(),
|
||||
None => {
|
||||
let campaign = message.get_meta_string("campaign")?;
|
||||
let tenant = message.get_meta_string("tenant")?;
|
||||
let domain = message.recipient()?.domain().to_string();
|
||||
match (campaign, tenant) {
|
||||
(Some(c), Some(t)) => format!("{c}:{t}@{domain}"),
|
||||
(Some(c), None) => format!("{c}:@{domain}"),
|
||||
(None, Some(t)) => format!("{t}@{domain}"),
|
||||
(None, None) => domain,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if queue_name != "null" {
|
||||
|
||||
@@ -227,6 +227,20 @@ impl Message {
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieve `key` as a String.
|
||||
pub fn get_meta_string<S: serde_json::value::Index + std::fmt::Display + Copy>(
|
||||
&self,
|
||||
key: S,
|
||||
) -> anyhow::Result<Option<String>> {
|
||||
match self.get_meta(key) {
|
||||
Ok(serde_json::Value::String(value)) => Ok(Some(value.to_string())),
|
||||
Ok(serde_json::Value::Null) => Ok(None),
|
||||
hmm => {
|
||||
anyhow::bail!("expected '{key}' to be a string value, got {hmm:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_meta<S: serde_json::value::Index>(
|
||||
&self,
|
||||
key: S,
|
||||
|
||||
Reference in New Issue
Block a user