Search in sources :

Example 1 with ServerSideConnectPayload

use of won.owner.pojo.ServerSideConnectPayload in project webofneeds by researchstudio-sat.

the class ServerSideActionController method connectSockets.

// rsponses: 204 (no content) or 409 (conflict)
@RequestMapping(value = "/connect", method = RequestMethod.POST)
public ResponseEntity connectSockets(@RequestBody(required = true) ServerSideConnectPayload connectAction) {
    String username = SecurityContextHolder.getContext().getAuthentication().getName();
    // cannot use user object from context since hw doesn't know about created in
    // this session atom,
    // therefore, we have to retrieve the user object from the user repository
    User user = userService.getByUsername(username);
    if (user == null) {
        return new ResponseEntity("Cannot process connect action: not logged in.", HttpStatus.FORBIDDEN);
    }
    if (StringUtils.isEmpty(connectAction.getFromSocket())) {
        return new ResponseEntity("Cannot process connect action: from socket not specified.", HttpStatus.CONFLICT);
    }
    if (StringUtils.isEmpty(connectAction.getToSocket())) {
        return new ResponseEntity("Cannot process connect action: to socket not specified.", HttpStatus.CONFLICT);
    }
    Set<UserAtom> atoms = user.getUserAtoms();
    if (!(connectAction.isFromPending() || atoms.stream().anyMatch(atom -> connectAction.getFromSocket().startsWith(atom.getUri().toString())))) {
        return new ResponseEntity("Cannot process connect action: from atom is not owned nor in pending.", HttpStatus.CONFLICT);
    }
    if (connectAction.isAutoOpen() && !(connectAction.isToPending() || atoms.stream().anyMatch(atom -> connectAction.getToSocket().startsWith(atom.getUri().toString())))) {
        return new ResponseEntity("Cannot process connect autoOpen action: to atom is not owned nor in pending.", HttpStatus.CONFLICT);
    }
    serverSideActionService.connect(connectAction, SecurityContextHolder.getContext().getAuthentication());
    return new ResponseEntity(HttpStatus.NO_CONTENT);
}
Also used : StringUtils(org.apache.commons.lang.StringUtils) UserAtom(won.owner.model.UserAtom) Autowired(org.springframework.beans.factory.annotation.Autowired) RequestMapping(org.springframework.web.bind.annotation.RequestMapping) RequestMethod(org.springframework.web.bind.annotation.RequestMethod) Set(java.util.Set) Controller(org.springframework.stereotype.Controller) UserAtomRepository(won.owner.repository.UserAtomRepository) ServerSideConnectPayload(won.owner.pojo.ServerSideConnectPayload) RequestBody(org.springframework.web.bind.annotation.RequestBody) HttpStatus(org.springframework.http.HttpStatus) User(won.owner.model.User) ServerSideActionService(won.owner.web.service.ServerSideActionService) ResponseEntity(org.springframework.http.ResponseEntity) SecurityContextHolder(org.springframework.security.core.context.SecurityContextHolder) UserService(won.owner.service.impl.UserService) ResponseEntity(org.springframework.http.ResponseEntity) User(won.owner.model.User) UserAtom(won.owner.model.UserAtom) RequestMapping(org.springframework.web.bind.annotation.RequestMapping)

Example 2 with ServerSideConnectPayload

use of won.owner.pojo.ServerSideConnectPayload 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));
}
Also used : StringUtils(org.apache.commons.lang.StringUtils) LinkedDataSource(won.protocol.util.linkeddata.LinkedDataSource) Arrays(java.util.Arrays) AuthenticationThreadLocal(won.protocol.util.AuthenticationThreadLocal) EventTriggeredAction(won.owner.web.service.serversideaction.EventTriggeredAction) OwnerApplicationService(won.owner.service.impl.OwnerApplicationService) Autowired(org.springframework.beans.factory.annotation.Autowired) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Function(java.util.function.Function) WonMessageDirection(won.protocol.message.WonMessageDirection) ServerSideConnectPayload(won.owner.pojo.ServerSideConnectPayload) WonMessage(won.protocol.message.WonMessage) WonMessageBuilder(won.protocol.message.builder.WonMessageBuilder) EventTriggeredActionContainer(won.owner.web.service.serversideaction.EventTriggeredActionContainer) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) WonMessageProcessingException(won.protocol.exception.WonMessageProcessingException) WonMessageProcessor(won.protocol.message.processor.WonMessageProcessor) URI(java.net.URI) WonNodeInformationService(won.protocol.service.WonNodeInformationService) WonMessageType(won.protocol.message.WonMessageType) Collection(java.util.Collection) Component(org.springframework.stereotype.Component) Optional(java.util.Optional) Authentication(org.springframework.security.core.Authentication) Collections(java.util.Collections) Optional(java.util.Optional) EventTriggeredAction(won.owner.web.service.serversideaction.EventTriggeredAction) URI(java.net.URI) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Function(java.util.function.Function) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) WonMessage(won.protocol.message.WonMessage) Collection(java.util.Collection)

Aggregations

StringUtils (org.apache.commons.lang.StringUtils)2 Autowired (org.springframework.beans.factory.annotation.Autowired)2 ServerSideConnectPayload (won.owner.pojo.ServerSideConnectPayload)2 URI (java.net.URI)1 Arrays (java.util.Arrays)1 Collection (java.util.Collection)1 Collections (java.util.Collections)1 Optional (java.util.Optional)1 Set (java.util.Set)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 Function (java.util.function.Function)1 HttpStatus (org.springframework.http.HttpStatus)1 ResponseEntity (org.springframework.http.ResponseEntity)1 Authentication (org.springframework.security.core.Authentication)1 SecurityContextHolder (org.springframework.security.core.context.SecurityContextHolder)1 Component (org.springframework.stereotype.Component)1 Controller (org.springframework.stereotype.Controller)1 RequestBody (org.springframework.web.bind.annotation.RequestBody)1 RequestMapping (org.springframework.web.bind.annotation.RequestMapping)1