All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.vaadin.collaborationengine.TopicConnectionRegistration Maven / Gradle / Ivy

/*
 * Copyright 2020-2022 Vaadin Ltd.
 *
 * This program is available under Commercial Vaadin Runtime License 1.0
 * (CVRLv1).
 *
 * For the full License, see http://vaadin.com/license/cvrl-1
 */
package com.vaadin.collaborationengine;

import java.util.EventObject;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;

import com.vaadin.flow.function.SerializableFunction;
import com.vaadin.flow.server.Command;
import com.vaadin.flow.shared.Registration;

/**
 * A registration for configuring or removing a topic connection that is opened
 * with Collaboration Engine.
 *
 * @see CollaborationEngine#openTopicConnection(ConnectionContext, String,
 *      UserInfo, SerializableFunction)
 *
 * @author Vaadin Ltd
 * @since 3.0
 */
public class TopicConnectionRegistration implements Registration {

    /**
     * An action for handling a failed topic connection.
     *
     * @see TopicConnectionRegistration#onConnectionFailed(ConnectionFailedAction)
     *
     * @author Vaadin Ltd
     */
    @FunctionalInterface
    public interface ConnectionFailedAction {
        /**
         * Handles a failed topic connection.
         *
         * @param event
         *            the connection failed event
         */
        void onConnectionFailed(ConnectionFailedEvent event);
    }

    /**
     * An event that is fired when the topic connection fails.
     *
     * @see TopicConnectionRegistration#onConnectionFailed(ConnectionFailedAction)
     *
     * @author Vaadin Ltd
     */
    public static class ConnectionFailedEvent extends EventObject {
        ConnectionFailedEvent(TopicConnectionRegistration source) {
            super(source);
        }

        @Override
        public TopicConnectionRegistration getSource() {
            return (TopicConnectionRegistration) super.getSource();
        }
    }

    private final AtomicReference topicConnectionReference;
    private ConnectionContext connectionContext;
    private Executor executor;
    private CompletableFuture pendingFuture;
    private final Consumer afterDisconnection;

    TopicConnectionRegistration(TopicConnection topicConnection,
            ConnectionContext connectionContext, Executor executor,
            Consumer afterDisconnection) {
        this.topicConnectionReference = new AtomicReference<>(topicConnection);
        this.connectionContext = connectionContext;
        this.executor = executor;
        this.afterDisconnection = afterDisconnection;
    }

    /**
     * Closes the topic connection. NO-OP if the connection has failed.
     */
    @Override
    public void remove() {
        TopicConnection topicConnection = topicConnectionReference
                .getAndSet(null);
        if (topicConnection != null) {
            pendingFuture = topicConnection.deactivateAndClose();
            pendingFuture.thenRun(() -> {
                this.pendingFuture = null;
                this.afterDisconnection.accept(this);
            });
        }
        connectionContext = null;
        executor = null;
    }

    Optional> getPendingFuture() {
        return Optional.ofNullable(pendingFuture);
    }

    /**
     * Adds an action to be executed if the topic connection fails. The
     * connection can fail in production mode, if your Collaboration Engine
     * license has expired, or if the number of unique monthly end users has
     * exceeded the quota in your license.
     * 

* If the connection has already failed when calling this method, the action * runs immediately. *

* The action is executed through * {@link ActionDispatcher#dispatchAction(Command)} of the connection * context that was used to open the connection. * * @param connectionFailedAction * the action to handle topic connection failure, not * {@code null} */ public void onConnectionFailed( ConnectionFailedAction connectionFailedAction) { Objects.requireNonNull(connectionFailedAction, "The connection failed action can't be null"); /* * With the embedded CE, we always know already at this point whether * the connection has failed or not, so there's no need to store the * action for later. This needs to be updated when we have the * standalone CE server. */ if (topicConnectionReference.get() == null) { connectionContext .init(new SingleUseActivationHandler(actionDispatcher -> { ConnectionFailedEvent event = new ConnectionFailedEvent( this); actionDispatcher .dispatchAction(() -> connectionFailedAction .onConnectionFailed(event)); }), executor); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy