package dslab.protocol.dmtp; import dslab.protocol.Message; import dslab.routing.Address; import dslab.routing.Domain; import java.util.Collection; import static dslab.protocol.MessageBuilder.aMessage; import static dslab.util.Utils.listElements; import static java.util.stream.Collectors.groupingBy; import static java.util.stream.Collectors.toSet; /** * A message where all recipients are from the same domain. This facilitates delivery. */ public class SingleDomainMessage extends Message { /** * @param message where all recipients are from the same domain */ public SingleDomainMessage(Message message) { super(message); var recipientDomains = recipients.stream().map(Address::getDomain).collect(toSet()); if (recipientDomains.size() != 1) throw new IllegalArgumentException("Expected " + message + " to have recipients from exactly one domain, " + "but found " + recipientDomains.size() + ": " + listElements(recipientDomains)); } /** * Splits the given {@link Message} with recipients from multiple domains into a collection of {@link SingleDomainMessage}s with * each having recipients of just a single domain. Other fields remain unchanged. * E.g. a message to a@foo.com, b@foo.com, c@bar.com is transformed into a collection of two messages, * one to a@foo.com,b@foo.com, the second to c@bar.com */ public static Collection split(Message message) { return message.getRecipients() .stream() .collect(groupingBy(Address::getDomain)) .values() .stream() .map(recipients -> new SingleDomainMessage(aMessage(message).recipients(recipients).build())) .collect(toSet()); } public Domain getRecipientDomain() { return recipients.iterator().next().getDomain(); } }