use of won.owner.web.service.serversideaction.EventTriggeredAction in project webofneeds by researchstudio-sat.
the class ServerSideActionService method connect.
/**
* Connect the specified sockets, optionally waiting until the respective atoms
* have been created. Use the specified authentication for sending messages on
* behalf of the user the authentication was obtained from.
*/
public void connect(ServerSideConnectPayload connectAction, Authentication authentication) {
// a little bit of shared state for the actions we are creating:
if (StringUtils.isEmpty(connectAction.getFromSocket()) || StringUtils.isEmpty(connectAction.getToSocket())) {
throw new IllegalArgumentException("From and To Socket expected");
}
// we want to have 2 atoms before we can start connecting:
final AtomicInteger atomCounter = new AtomicInteger(0);
final AtomicBoolean connectSent = new AtomicBoolean(false);
final URI fromSocket = URI.create(connectAction.getFromSocket());
final String message = connectAction.getMessage();
final URI toSocket = URI.create(connectAction.getToSocket());
// count the sockets that are NOT pending (= the number of atoms that have
// already been created)
int atoms = 2;
if (connectAction.isFromPending()) {
atoms--;
}
if (connectAction.isToPending()) {
atoms--;
}
atomCounter.set(atoms);
final Function<Optional<WonMessage>, Collection<EventTriggeredAction<WonMessage>>> action = new Function<Optional<WonMessage>, Collection<EventTriggeredAction<WonMessage>>>() {
@Override
public Collection<EventTriggeredAction<WonMessage>> apply(Optional<WonMessage> msg) {
// process success responses for create
if (msg.isPresent() && atomCounter.get() < 2 && isResponseToCreateOfSockets(msg.get(), connectAction)) {
// we're processing a response event for the creation of one of our atoms.
atomCounter.incrementAndGet();
}
// event:
if (atomCounter.get() >= 2) {
// we have all the atoms we need for the connect.
if (connectSent.compareAndSet(false, true)) {
// we haven't sent the connect yet, do it now and register a new action
// waiting for the connect on the receiving end.
sendConnect(fromSocket, toSocket, message, authentication);
return Arrays.asList(new EventTriggeredAction<WonMessage>(String.format("Connect %s and %s: Expecting incoming connect from %s for %s", fromSocket, toSocket, fromSocket, toSocket), m -> isConnectFromSocketForSocket(m.get(), fromSocket, toSocket), this));
} else {
// receiving end. If so, send an open.
if (connectAction.isAutoOpen() && isConnectFromSocketForSocket(msg.get(), fromSocket, toSocket)) {
reactWithConnect(msg.get(), message, authentication);
// that's it - don't register any more actions
}
}
} else {
// for another create response
return Arrays.asList(new EventTriggeredAction<>(String.format("Connect %s and %s: Expecting response for create", fromSocket, toSocket), m -> m.isPresent() && isResponseToCreateOfSockets(m.get(), connectAction), this));
}
// none of the above - this is the last execution of this action.
return Collections.emptyList();
}
};
// add the action in such a way that it is triggered on add (with an empty
// Optional<WonMessage>)
this.actionContainer.addAction(new EventTriggeredAction<WonMessage>(String.format("Connect %s and %s", fromSocket, toSocket), action));
}
Aggregations