Files

89 lines
2.7 KiB
Java

record DynamicRoute(String from, String to) {}
DynamicRoute readRoute(Message message, String controlMailbox) {
var mailboxes = message.value().lines().toList();
if (mailboxes.size() != 2
|| mailboxes.get(0).isBlank()
|| mailboxes.get(1).isBlank()) {
IO.println("ROUTE needs exactly two lines: <from> and <to>");
return null;
}
var route = new DynamicRoute(mailboxes.get(0), mailboxes.get(1));
try {
FileMessageBoard.directory(route.from());
FileMessageBoard.directory(route.to());
} catch (IllegalArgumentException exception) {
IO.println("Rejected ROUTE: " + exception.getMessage());
return null;
}
if (route.from().equals(route.to())) {
IO.println("Rejected ROUTE: from and to must differ");
return null;
}
if (route.from().equals(controlMailbox)
|| route.to().equals(controlMailbox)) {
IO.println("Rejected ROUTE: the control mailbox is not a data mailbox");
return null;
}
return route;
}
void main(String[] arguments) throws Exception {
if (arguments.length != 1
|| !arguments[0].matches("[A-Za-z0-9_-]+")) {
IO.println("Usage: java DynamicMediatorService.java <mediator-name>");
return;
}
var name = arguments[0];
var controlMailbox = "mediators/" + name + "/inbox";
try (var subscriptions = new FileSubscriptions()) {
DynamicRoute route = null;
subscriptions.subscribe(controlMailbox);
IO.println(name + " waits for ROUTE on " + controlMailbox);
while (true) {
var incoming = subscriptions.take();
var message = incoming.message();
if (incoming.mailbox().equals(controlMailbox)) {
if (!message.type().equals("ROUTE")) {
IO.println("Ignored " + message.type() + "; expected ROUTE");
continue;
}
var requestedRoute = readRoute(message, controlMailbox);
if (requestedRoute == null)
continue;
if (route == null
|| !route.from().equals(requestedRoute.from())) {
subscriptions.subscribe(requestedRoute.from());
if (route != null)
subscriptions.unsubscribe(route.from());
}
route = requestedRoute;
IO.println(
name + " now mediates: "
+ route.from() + " -> " + route.to()
);
} else if (route != null
&& incoming.mailbox().equals(route.from())) {
FileMessageBoard.publish(route.to(), message);
}
}
}
}