package dslab.mailbox; import dslab.authentication.AuthenticationService; import dslab.authentication.User; import dslab.protocol.Message; import dslab.routing.Address; import dslab.routing.AddressResolutionException; import dslab.routing.DeliveryService; import dslab.routing.Domain; import java.util.List; import java.util.Map; import java.util.logging.Logger; import static dslab.util.Utils.listElements; import static java.util.function.Function.identity; import static java.util.stream.Collectors.*; /** * Manages the mailboxes for all users on a server. */ public class MailboxManager implements DeliveryService { private final Domain home; private final Map mailboxes; private final AuthenticationService authenticationService; private static final Logger LOG = Logger.getLogger(MailboxManager.class.getSimpleName()); public MailboxManager(Domain home, AuthenticationService authenticationService) { this.authenticationService = authenticationService; this.home = home; mailboxes = this.authenticationService .getUsers() .stream() .collect(toConcurrentMap(identity(), Mailbox::new)); } public Message getMessage(Integer messageId) throws MessageNotFoundException { return getMailbox(authenticationService.getLoggedInUser()).get(messageId); } public Mailbox getMailbox(User user) { if (!hasMailbox(user)) throw new IllegalArgumentException("The user " + user + " doesn't exist"); return mailboxes.get(user); } public boolean hasMailbox(User user) { return mailboxes.containsKey(user); } public void deleteMessage(Integer messageId) throws MessageNotFoundException { var loggedInUser = authenticationService.getLoggedInUser(); mailboxes.get(loggedInUser).deleteMessage(messageId); } @Override public void deliver(Message message) { for (Address recipient : message.getRecipients()) for (var entry : mailboxes.entrySet()) if (entry.getKey().getAddress().equals(recipient)) { entry.getValue().put(message); } LOG.info("Message sent: " + message); } /** * @return the number of addresses that this mailbox will store * @throws AddressResolutionException if there are addresses that belong to this domain * of which the server doesn't recognize the user part */ @Override public Integer validateAddresses(List
addresses) throws AddressResolutionException { var addressesManagedByThisServer = addresses.stream().filter(address -> address.getDomain().equals(home)).collect(toList()); //see assignment 1, sec. 2.5 'accepting messages' if (addressesManagedByThisServer.size() == 0) throw new AddressResolutionException("None of the addresses in " + listElements(addresses) + " are part of the home domain " + home); var unknownAddresses = addressesManagedByThisServer.stream() .filter(x -> !authenticationService.knows(x)) .map(Address::toString) .collect(joining(",")); if (!unknownAddresses.isEmpty()) { LOG.info("User part of " + unknownAddresses + " is illegal" + "in list of addresses " + listElements(addresses)); throw new AddressResolutionException("The addresses " + unknownAddresses + " could not be resolved"); } return addressesManagedByThisServer.size(); } }