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

com.pushtechnology.diffusion.client.features.control.topics.SubscriptionControl Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright (c) 2023 DiffusionData Ltd., All Rights Reserved.
 *
 * Use is subject to license terms.
 *
 * NOTICE: All information contained herein is, and remains the
 * property of Push Technology. The intellectual and technical
 * concepts contained herein are proprietary to Push Technology and
 * may be covered by U.S. and Foreign Patents, patents in process, and
 * are protected by trade secret or copyright law.
 *******************************************************************************/
package com.pushtechnology.diffusion.client.features.control.topics;

import static org.slf4j.LoggerFactory.getLogger;

import java.util.Collection;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.pushtechnology.diffusion.client.callbacks.Callback;
import com.pushtechnology.diffusion.client.callbacks.ContextCallback;
import com.pushtechnology.diffusion.client.callbacks.Registration;
import com.pushtechnology.diffusion.client.callbacks.Stream;
import com.pushtechnology.diffusion.client.features.HandlerConflictException;
import com.pushtechnology.diffusion.client.features.InvalidFilterException;
import com.pushtechnology.diffusion.client.features.NoSuchSessionException;
import com.pushtechnology.diffusion.client.features.TopicTreeHandler;
import com.pushtechnology.diffusion.client.features.control.clients.ClientControl.SessionPropertiesListener;
import com.pushtechnology.diffusion.client.session.Feature;
import com.pushtechnology.diffusion.client.session.PermissionsException;
import com.pushtechnology.diffusion.client.session.Session;
import com.pushtechnology.diffusion.client.session.SessionClosedException;
import com.pushtechnology.diffusion.client.session.SessionException;
import com.pushtechnology.diffusion.client.session.SessionId;
import com.pushtechnology.diffusion.client.topics.TopicSelector;
import com.pushtechnology.diffusion.client.topics.TopicSelectors;
import com.pushtechnology.diffusion.client.topics.details.TopicType;
import com.pushtechnology.diffusion.client.types.ErrorReport;
import com.pushtechnology.diffusion.client.types.GlobalPermission;
import com.pushtechnology.diffusion.client.types.PathPermission;

/**
 * This feature allows a session to subscribe or unsubscribe other sessions to
 * topics. It also provides a mechanism for handling requests to subscribe to
 * routing topics (deprecated).
 * 

* Requests to subscribe sessions to topics can be submitted at any time even if * the topics do not exist at the server. {@link TopicSelector Topic selectors} * are used on subscription to match against topics at the server. The session * will become subscribed to any topics that exist at the server that match the * selector (unless they are already subscribed, or the session has insufficient * permission). The subscription request is also retained at the server so that * if any newly created topics match the selector, the session will then become * subscribed to it (unless a subsequent unsubscription cancels it). *

* Specific sessions may be subscribed/unsubscribed if the {@link SessionId} is * known. *

* Subscriptions may also be requested using 'session filters' (see * {@link Session} for a full description of session filters), where all * sessions that satisfy a particular filter expression will be * subscribed/unsubscribed. The filter is only evaluated once against the * current sessions that exist at the time - it is not retained and applied to * any sessions that are created later. In order to be notified of new sessions * as they are created {@link SessionPropertiesListener session properties * listeners} can be used and those sessions subscribed as required based upon * their session properties. * *

* A handler for routing topics belonging to a branch of the topic tree can be * added using * {@link #addRoutingSubscriptionHandler(String, SubscriptionControl.RoutingSubscriptionRequest.RoutingHandler) * addRoutingSubscriptionHandler()}. When another session subscribes to one of * the routing topics, the handler will be called to determine the appropriate * source topic. * *

Access control

To subscribe other sessions to topics, a session must * have {@link GlobalPermission#MODIFY_SESSION MODIFY_SESSION} permission, and * {@link PathPermission#SELECT_TOPIC SELECT_TOPIC} permission for the path * prefix of the topic selector used for subscription. The subscribed sessions * will only be subscribed to matching topics for which they have * {@link PathPermission#READ_TOPIC READ_TOPIC} permission. *

* To unsubscribe other sessions, a session must have * {@link GlobalPermission#MODIFY_SESSION MODIFY_SESSION} permission. *

* To register a {@link #addRoutingSubscriptionHandler routing subscription * handler} the session needs {@link GlobalPermission#VIEW_SESSION * VIEW_SESSION}, {@link GlobalPermission#MODIFY_SESSION MODIFY_SESSION} and * {@link GlobalPermission#REGISTER_HANDLER REGISTER_HANDLER} permissions. *

* When handling a subscription request to a routing topic via a routing handler * the routing session needs {@link PathPermission#READ_TOPIC READ_TOPIC} * permission to both the routing topic being subscribed to and the target topic * that is assigned. *

* Operations that identify sessions using a session filter require the * {@link GlobalPermission#VIEW_SESSION VIEW_SESSION} permission. * *

Accessing the feature

This feature may be obtained from a * {@link Session session} as follows: * *
 * 
 * SubscriptionControl subsControl = session.feature(SubscriptionControl.class);
 * 
 * 
* * @author DiffusionData Limited * @since 5.0 */ public interface SubscriptionControl extends Feature { /** * Adds a handler for {@link TopicType#ROUTING routing} topics that belong * to a branch of the topic tree. When another session subscribes to one of * the routing topics, the handler will be called to determine the * appropriate source topic. * *

* For each subscription to the routing topic, the server will select a * handler registered for the most specific branch. If multiple handlers are * registered for the same branch, the server will select one of them * arbitrarily. * * @param topicPath identifies the branch of the topic tree to associate the * handler with * * @param handler the handler to use for routing topics at or below the * specified path (unless there is a handler registered for a more * specific topic path) * * @return a CompletableFuture that completes when the handler is registered * with the server. * *

* If registration was successful, the CompletableFuture will * complete successfully with a {@link Registration} which can be * used to unregister the handler. * *

* Otherwise, the CompletableFuture will complete exceptionally with * a {@link CompletionException}. Common reasons for failure, listed * by the exception reported as the * {@link CompletionException#getCause() cause}, include: * *

    *
  • {@link HandlerConflictException} – if the session has * already registered a routing subscription handler for * {@code topicPath}; * *
  • {@link PermissionsException} – if the session does * not have {@code REGISTER_HANDLER} permission; * *
  • {@link PermissionsException} – if the session does * not have {@code VIEW_SESSION} permission; * *
  • {@link PermissionsException} – if the session does * not have {@code MODIFY_SESSION} permission; * *
  • {@link SessionClosedException} – if the session is * closed. *
* * @since 6.0 * @deprecated since 6.7 *

* Routing topics are deprecated. The more powerful * {@link SessionTrees} feature should be used in their place. */ @Deprecated CompletableFuture addRoutingSubscriptionHandler( String topicPath, RoutingSubscriptionRequest.RoutingHandler handler); /** * Adds a handler for {@link TopicType#ROUTING routing} topics that belong * to a branch of the topic tree. When another session subscribes to one of * the routing topics, the handler will be called to determine the * appropriate source topic. * *

* The CompletableFuture-based alternative * {@link SubscriptionControl#addRoutingSubscriptionHandler(String, com.pushtechnology.diffusion.client.features.control.topics.SubscriptionControl.RoutingSubscriptionRequest.RoutingHandler) * addRoutingSubscriptionHandler(String, RoutingHandler)} should be * preferred since it provides better error reporting. * *

* For each subscription to the routing topic, the server will select a * handler registered for the most specific branch. If multiple handlers are * registered for the same branch, the server will select one of them * arbitrarily. * * @param topicPath identifies the branch of the topic tree to associate the * handler with * * @param handler the handler to use for routing topics at or below the * specified path (unless there is a handler registered for a * more specific topic path) * * @deprecated since 6.7 *

* Routing topics are deprecated. The more powerful * {@link SessionTrees} feature should be used in their place. */ @Deprecated void addRoutingSubscriptionHandler( String topicPath, RoutingSubscriptionRequest.Handler handler); /** * Subscribe another session to topics. * *

* This is equivalent to calling * {@link #subscribe(SessionId, TopicSelector)} with a selector parsed using * {@link TopicSelectors#parse(String)}. * * @param sessionId identifies the session to subscribe * * @param topics the topics to subscribe to specified as a * {@link TopicSelector} expression * * @return a CompletableFuture that completes when the server has processed * the subscription request. * *

* If the subscription was accepted, the CompletableFuture will * complete successfully. The result type is any rather than Void * to provide forward compatibility with future iterations of this * API that may provide a non-null result with a more specific * result type. * *

* Otherwise, the CompletableFuture will complete exceptionally with * a {@link CompletionException}. Common reasons for failure, listed * by the exception reported as the * {@link CompletionException#getCause() cause}, include: * *

    *
  • {@link PermissionsException} – if the calling * session does not have {@code MODIFY_SESSION} permission; * *
  • {@link PermissionsException} – if the calling * session does not have {@code SELECT_TOPIC} permission for the * path prefix of the selector expression ; * *
  • {@link NoSuchSessionException} – if there is no session * with the given {@code sessionId}; * *
  • {@link SessionClosedException} – if the session is * closed. *
* * @throws IllegalArgumentException if {@code topics} is not a valid * selector expression * @since 6.0 */ CompletableFuture subscribe( SessionId sessionId, String topics) throws IllegalArgumentException; /** * Subscribe another session to topics. * *

* New subscriptions will be established for existing topics that match the * provided topic selector and for which the subscribed session has * {@code READ_TOPIC} permission. The topic selector will be added to the * topic selections of the subscribed session, and re-evaluated when new * topics are added or the session's security roles change. * *

* A session that does not have {@code SELECT_TOPIC} permission for a topic * cannot subscribe directly, but can be subscribed indirectly using this * method. * * @param sessionId identifies the session to subscribe * * @param topics identifies the topics to subscribe to * * @return a CompletableFuture that completes when the server has processed * the subscription request. * *

* If the subscription was accepted, the CompletableFuture will * complete successfully. The result type is any rather than Void * to provide forward compatibility with future iterations of this * API that may provide a non-null result with a more specific * result type. * *

* Otherwise, the CompletableFuture will complete exceptionally with * a {@link CompletionException}. Common reasons for failure, listed * by the exception reported as the * {@link CompletionException#getCause() cause}, include: * *

    *
  • {@link PermissionsException} – if the calling * session does not have {@code MODIFY_SESSION} permission; * *
  • {@link PermissionsException} – if the calling * session does not have {@code SELECT_TOPIC} permission for the * path prefix of the selector expression ; * *
  • {@link NoSuchSessionException} – if there is no session * with the given {@code sessionId}; * *
  • {@link SessionClosedException} – if the session is * closed. *
* @since 6.0 */ CompletableFuture subscribe( SessionId sessionId, TopicSelector topics); /** * Subscribe another session to topics. * *

* This is equivalent to calling * {@link #subscribe(SessionId, TopicSelector, SubscriptionCallback)} with a * selector parsed using {@link TopicSelectors#parse(String)}. * * @param sessionId identifies the session to subscribe * * @param topics the topics to subscribe to specified as a * {@link TopicSelector} expression * * @param callback provides callback methods to indicate success or failure * * @throws IllegalArgumentException if {@code topics} is not a valid * selector expression * * @deprecated since 6.7 *

* Methods that use callbacks are deprecated and will be removed * in a future release. Use CompletableFuture variant instead. */ @Deprecated void subscribe( SessionId sessionId, String topics, SubscriptionCallback callback) throws IllegalArgumentException; /** * Subscribe another session to topics. * *

* New subscriptions will be established for existing topics that match the * provided topic selector and for which the subscribed session has * {@code READ_TOPIC} permission. The topic selector will be added to the * topic selections of the subscribed session, and re-evaluated when new * topics are added or the session's security roles change. * *

* A session that does not have {@code SELECT_TOPIC} permission for a topic * cannot subscribe directly, but can be subscribed indirectly using this * method. * * @param sessionId identifies the session to subscribe * * @param topics identifies the topics to subscribe to * * @param callback provides callback methods to indicate success or failure * * @deprecated since 6.7 *

* Methods that use callbacks are deprecated and will be removed * in a future release. Use CompletableFuture variant instead. */ @Deprecated void subscribe( SessionId sessionId, TopicSelector topics, SubscriptionCallback callback); /** * Subscribe another session to topics. * *

* This is equivalent to calling * {@link #subscribe(SessionId, TopicSelector, Object, SubscriptionContextCallback)} * with a selector parsed using {@link TopicSelectors#parse(String)}. * * @param sessionId identifies the session to subscribe * * @param topics the topics to subscribe to specified as a * {@link TopicSelector} expression * * @param context passed to the callback with the reply to allow requests * and replies to be correlated. The caller may use any convenient * object reference, including {@code null} * * @param callback provides callback methods to indicate success or failure * * @throws IllegalArgumentException if {@code topics} is not a valid * selector expression * * @param context object type * * @deprecated since 6.7 *

* Methods that use callbacks are deprecated and will be removed * in a future release. Use CompletableFuture variant instead. */ @Deprecated void subscribe( SessionId sessionId, String topics, C context, SubscriptionContextCallback callback) throws IllegalArgumentException; /** * Subscribe another session to topics. * *

* New subscriptions will be established for existing topics that match the * provided topic selector and for which the subscribed session has * {@code READ_TOPIC} permission. The topic selector will be added to the * topic selections of the subscribed session, and re-evaluated when new * topics are added or the session's security roles change. * *

* A session that does not have {@code SELECT_TOPIC} permission for a topic * cannot subscribe directly, but can be subscribed indirectly using this * method. * * @param sessionId identifies the session to subscribe * * @param topics identifies the topics to subscribe to * * @param context passed to the callback with the reply to allow requests * and replies to be correlated. The caller may use any convenient * object reference, including {@code null} * * @param callback provides callback methods to indicate success or failure * * @param context object type * * @deprecated since 6.7 *

* Methods that use callbacks are deprecated and will be removed * in a future release. Use CompletableFuture variant instead. */ @Deprecated void subscribe( SessionId sessionId, TopicSelector topics, C context, SubscriptionContextCallback callback); /** * Unsubscribe another session from topics. * *

* This is equivalent to calling * {@link #unsubscribe(SessionId, TopicSelector)} with a selector parsed * using {@link TopicSelectors#parse(String)}. * * @param sessionId identifies the session to unsubscribe * * @param topics the topics to unsubscribe specified as a * {@link TopicSelector} expression * * @return a CompletableFuture that completes when the server has processed * the unsubscription request. * *

* If the unsubscription was accepted, the CompletableFuture will * complete successfully. The result type is any rather than Void * to provide forward compatibility with future iterations of this * API that may provide a non-null result with a more specific * result type. * *

* Otherwise, the CompletableFuture will complete exceptionally with * a {@link CompletionException}. Common reasons for failure, listed * by the exception reported as the * {@link CompletionException#getCause() cause}, include: * *

    *
  • {@link PermissionsException} – if the calling * session does not have {@code MODIFY_SESSION} permission; * *
  • {@link NoSuchSessionException} – if there is no session * with the given {@code sessionId}; * *
  • {@link SessionClosedException} – if the session is * closed. *
* * @throws IllegalArgumentException if {@code topics} is not a valid * selector expression * @since 6.0 */ CompletableFuture unsubscribe( SessionId sessionId, String topics) throws IllegalArgumentException; /** * Unsubscribe another session from topics. * * @param sessionId identifies the session to unsubscribe * * @param topics the topics to unsubscribe from * * @return a CompletableFuture that completes when the server has processed * the unsubscription request. * *

* If the unsubscription was accepted, the CompletableFuture will * complete successfully. The result type is any rather than Void * to provide forward compatibility with future iterations of this * API that may provide a non-null result with a more specific * result type. * *

* Otherwise, the CompletableFuture will complete exceptionally with * a {@link CompletionException}. Common reasons for failure, listed * by the exception reported as the * {@link CompletionException#getCause() cause}, include: * *

    *
  • {@link PermissionsException} – if the calling * session does not have {@code MODIFY_SESSION} permission; * *
  • {@link NoSuchSessionException} – if there is no session * with the given {@code sessionId}; * *
  • {@link SessionClosedException} – if the session is * closed. *
* @since 6.0 */ CompletableFuture unsubscribe( SessionId sessionId, TopicSelector topics); /** * Unsubscribe another session from topics. * *

* This is equivalent to calling * {@link #unsubscribe(SessionId, TopicSelector, SubscriptionCallback)} * with a selector parsed using {@link TopicSelectors#parse(String)}. * * @param sessionId identifies the session to unsubscribe * * @param topics the topics to unsubscribe specified as a * {@link TopicSelector} expression * * @param callback provides callback methods indicating the status of this * operation * * @throws IllegalArgumentException if {@code topics} is not a valid * selector expression * * @deprecated since 6.7 *

* Methods that use callbacks are deprecated and will be removed * in a future release. Use CompletableFuture variant instead. */ @Deprecated void unsubscribe( SessionId sessionId, String topics, SubscriptionCallback callback) throws IllegalArgumentException; /** * Unsubscribe another session from topics. * * @param sessionId identifies the session to unsubscribe * * @param topics the topics to unsubscribe from * * @param callback provides callback methods indicating the status of this * operation * * @deprecated since 6.7 *

* Methods that use callbacks are deprecated and will be removed * in a future release. Use CompletableFuture variant instead. */ @Deprecated void unsubscribe( SessionId sessionId, TopicSelector topics, SubscriptionCallback callback); /** * Unsubscribe another session from topics. * *

* This is equivalent to calling * {@link #unsubscribe(SessionId, TopicSelector, Object, SubscriptionContextCallback)} * with a selector parsed using {@link TopicSelectors#parse(String)}. * * @param sessionId identifies the session to unsubscribe * * @param topics the topics to unsubscribe specified as a * {@link TopicSelector} expression * * @param context passed to the callback with the reply to allow requests * and replies to be correlated. The caller may use any convenient * object reference, including {@code null} * * @param callback provides callback methods indicating the status of this * operation * * @throws IllegalArgumentException if {@code topics} is not a valid * selector expression * * @param context object type * * @deprecated since 6.7 *

* Methods that use callbacks are deprecated and will be removed * in a future release. Use CompletableFuture variant instead. */ @Deprecated void unsubscribe( SessionId sessionId, String topics, C context, SubscriptionContextCallback callback) throws IllegalArgumentException; /** * Unsubscribe another session from topics. * * @param sessionId identifies the session to unsubscribe * * @param topics the topics to unsubscribe from * * @param context passed to the callback with the reply to allow requests * and replies to be correlated. The caller may use any convenient * object reference, including {@code null} * * @param callback provides callback methods indicating the status of this * operation * * @param context object type * * @deprecated since 6.7 *

* Methods that use callbacks are deprecated and will be removed * in a future release. Use CompletableFuture variant instead. */ @Deprecated void unsubscribe( SessionId sessionId, TopicSelector topics, C context, SubscriptionContextCallback callback); /** * Callback interface to receive status notifications for subscription and * unsubscription operations. * * @deprecated since 6.7 *

* Methods that use callbacks are deprecated and will be removed * in a future release. Use CompletableFuture variant instead. */ @Deprecated interface SubscriptionCallback extends com.pushtechnology.diffusion.client.features.Callback { /** * Called to indicate that the requested operation has been processed by * the server. */ void onComplete(); /** * Default implementation of {@link SubscriptionCallback}. *

* This simply logs onComplete calls at 'debug' level. This method may * be overridden to perform more specific processing. */ class Default extends com.pushtechnology.diffusion.client.features.Callback.Default implements SubscriptionCallback { private static final Logger LOG = getLogger(SubscriptionCallback.Default.class); @Override public void onComplete() { LOG.debug( "{} - Subscription/Unsubscription complete", this); } } } /** * Contextual callback interface to receive status notifications for * subscription and unsubscription operations. * *

* Use this alternative to {@link SubscriptionCallback} to associate some * arbitrary context object with each call. * * @param context object type * * @deprecated since 6.7 *

* Methods that use callbacks are deprecated and will be removed * in a future release. Use CompletableFuture variant instead. */ @Deprecated interface SubscriptionContextCallback extends com.pushtechnology.diffusion.client.features.ContextCallback { /** * Called to indicate that the requested operation has been processed by * the server. * * @param context the context object supplied when making the call. May * be {@code null}. */ void onComplete(C context); /** * Default implementation of {@link SubscriptionContextCallback}. *

* This simply logs onComplete calls at 'debug' level. This method may * be overridden to perform more specific processing. * * @param context object type */ class Default extends com.pushtechnology.diffusion.client.features.ContextCallback.Default implements SubscriptionContextCallback { private static final Logger LOG = getLogger(SubscriptionContextCallback.Default.class); @Override public void onComplete( C context) { LOG.debug( "{} - Subscription/Unsubscription complete, context={}", this, context); } } } /** * Subscribe sessions that satisfy a given session filter to topics. * *

* This is equivalent to calling * {@link #subscribeByFilter(String, TopicSelector)} with a selector parsed * using {@link TopicSelectors#parse(String)}. * * @param filter the session filter expression * * @param topics the topics to subscribe to specified as a * {@link TopicSelector} expression * * @return a CompletableFuture that completes when the server has processed * the subscription request. * *

* If the subscription was accepted, the CompletableFuture will * complete successfully with a {@link SubscriptionByFilterResult}. * *

* Otherwise, the CompletableFuture will complete exceptionally with * a {@link CompletionException}. Common reasons for failure, listed * by the exception reported as the * {@link CompletionException#getCause() cause}, include: * *

    *
  • {@link InvalidFilterException} – if the filter is * invalid; * *
  • {@link PermissionsException} – if the calling * session does not have {@code MODIFY_SESSION} and * {@code VIEW_SESSION} global permissions; * *
  • {@link PermissionsException} – if the calling * session does not have {@code SELECT_TOPIC} permission for the * path prefix of the selector expression; * *
  • {@link SessionClosedException} – if the session is * closed. *
* * @throws IllegalArgumentException if {@code topics} is not a valid * selector expression * * @since 6.0 */ CompletableFuture subscribeByFilter( String filter, String topics) throws IllegalArgumentException; /** * Subscribe sessions that satisfy a given session filter to topics. * *

* For each session that matches the filter, new subscriptions will be * established for existing topics that match the provided topic selector * and for which the sessions has {@code READ_TOPIC} permission. The topic * selector will be added to the topic selections of the subscribed session, * and re-evaluated when new topics are added or the session's security * roles change. * *

* A session that does not have {@code SELECT_TOPIC} permission for a topic * cannot subscribe directly, but can be subscribed indirectly using this * method. * * @param filter the session filter expression * * @param topics the topics to subscribe to specified as a * {@link TopicSelector} expression * * @return a CompletableFuture that completes when the server has processed * the subscription request. * *

* If the subscription was accepted, the CompletableFuture will * complete successfully with a {@link SubscriptionByFilterResult}. * *

* Otherwise, the CompletableFuture will complete exceptionally with * a {@link CompletionException}. Common reasons for failure, listed * by the exception reported as the * {@link CompletionException#getCause() cause}, include: * *

    *
  • {@link InvalidFilterException} – if the filter is * invalid; * *
  • {@link PermissionsException} – if the calling * session does not have {@code MODIFY_SESSION} and * {@code VIEW_SESSION} permissions; * *
  • {@link PermissionsException} – if the calling * session does not have {@code SELECT_TOPIC} permission for the * path prefix of the selector expression; * *
  • {@link SessionClosedException} – if the session is * closed. *
* * @since 6.0 */ CompletableFuture subscribeByFilter( String filter, TopicSelector topics); /** * Subscribe sessions that satisfy a given session filter to topics. * *

* This is equivalent to calling * {@link #subscribeByFilter(String, TopicSelector, SubscriptionByFilterCallback)} * with a selector parsed using {@link TopicSelectors#parse(String)}. * * @param filter the session filter expression * * @param topics the topics to subscribe to specified as a * {@link TopicSelector} expression * * @param callback provides callback methods to indicate success or failure * * @throws IllegalArgumentException if {@code topics} is not a valid * selector expression * * @since 5.6 * * @deprecated since 6.7 *

* Methods that use callbacks are deprecated and will be removed * in a future release. Use CompletableFuture variant instead. */ @Deprecated void subscribeByFilter( String filter, String topics, SubscriptionByFilterCallback callback) throws IllegalArgumentException; /** * Subscribe sessions that satisfy a given session filter to topics. * *

* For each session that matches the filter, new subscriptions will be * established for existing topics that match the provided topic selector * and for which the sessions has {@code READ_TOPIC} permission. The topic * selector will be added to the topic selections of the subscribed session, * and re-evaluated when new topics are added or the session's security * roles change. * *

* A session that does not have {@code SELECT_TOPIC} permission for a topic * cannot subscribe directly, but can be subscribed indirectly using this * method. * * @param filter the session filter expression * * @param topics identifies the topics to subscribe to * * @param callback provides callback methods to indicate success or failure * * @since 5.6 * * @deprecated since 6.7 *

* Methods that use callbacks are deprecated and will be removed * in a future release. Use CompletableFuture variant instead. */ @Deprecated void subscribeByFilter( String filter, TopicSelector topics, SubscriptionByFilterCallback callback); /** * Subscribe sessions that satisfy a given session filter to topics. * *

* This is equivalent to calling * {@link #subscribeByFilter(String, TopicSelector, Object, SubscriptionByFilterContextCallback)} * with a selector parsed using {@link TopicSelectors#parse(String)}. * * @param filter the session filter expression * * @param topics the topics to subscribe to specified as a * {@link TopicSelector} expression * * @param context passed to the callback with the reply to allow requests * and replies to be correlated. The caller may use any convenient * object reference, including {@code null} * * @param callback provides callback methods to indicate success or failure * * @throws IllegalArgumentException if {@code topics} is not a valid * selector expression * * @param context object type * * @since 5.6 * * @deprecated since 6.7 *

* Methods that use callbacks are deprecated and will be removed * in a future release. Use CompletableFuture variant instead. */ @Deprecated void subscribeByFilter( String filter, String topics, C context, SubscriptionByFilterContextCallback callback) throws IllegalArgumentException; /** * Subscribe sessions that satisfy a given session filter to topics. * *

* For each session that matches the filter, new subscriptions will be * established for existing topics that match the provided topic selector * and for which the sessions has {@code READ_TOPIC} permission. The topic * selector will be added to the topic selections of the subscribed session, * and re-evaluated when new topics are added or the session's security * roles change. * *

* A session that does not have {@code SELECT_TOPIC} permission for a topic * cannot subscribe directly, but can be subscribed indirectly using this * method. * * @param filter the session filter expression * * @param topics identifies the topics to subscribe to * * @param context passed to the callback with the reply to allow requests * and replies to be correlated. The caller may use any convenient * object reference, including {@code null} * * @param callback provides callback methods to indicate success or failure * * @param context object type * * @since 5.6 * * @deprecated since 6.7 *

* Methods that use callbacks are deprecated and will be removed * in a future release. Use CompletableFuture variant instead. */ @Deprecated void subscribeByFilter( String filter, TopicSelector topics, C context, SubscriptionByFilterContextCallback callback); /** * Unsubscribe sessions that satisfy a given session filter from topics. * *

* This is equivalent to calling * {@link #unsubscribeByFilter(String, TopicSelector)} with a selector * parsed using {@link TopicSelectors#parse(String)}. * * @param filter the session filter expression * * @param topics the topics to unsubscribe from specified as a * {@link TopicSelector} expression * * @return a CompletableFuture that completes when the server has processed * the unsubscription request. * *

* If the unsubscription was accepted, the CompletableFuture will * complete successfully with a {@link SubscriptionByFilterResult}. * *

* Otherwise, the CompletableFuture will complete exceptionally with * a {@link CompletionException}. Common reasons for failure, listed * by the exception reported as the * {@link CompletionException#getCause() cause}, include: * *

    *
  • {@link InvalidFilterException} – if the filter is * invalid; * *
  • {@link PermissionsException} – if the calling * session does not have {@code MODIFY_SESSION} and * {@code VIEW_SESSION} permissions; * *
  • {@link SessionClosedException} – if the session is * closed. *
* * @throws IllegalArgumentException if {@code topics} is not a valid * selector expression * * @since 6.0 */ CompletableFuture unsubscribeByFilter( String filter, String topics) throws IllegalArgumentException; /** * Unsubscribe sessions that satisfy a given session filter from topics. * * @param filter the session filter expression * * @param topics the topics to unsubscribe from specified as a * {@link TopicSelector} expression * * @return a CompletableFuture that completes when the server has processed * the unsubscription request. * *

* If the unsubscription was accepted, the CompletableFuture will * complete successfully with a {@link SubscriptionByFilterResult}. * *

* Otherwise, the CompletableFuture will complete exceptionally with * a {@link CompletionException}. Common reasons for failure, listed * by the exception reported as the * {@link CompletionException#getCause() cause}, include: * *

    *
  • {@link InvalidFilterException} – if the filter is * invalid; * *
  • {@link PermissionsException} – if the calling * session does not have {@code MODIFY_SESSION} and * {@code VIEW_SESSION} global permissions; * *
  • {@link SessionClosedException} – if the session is * closed. *
* * @since 6.0 */ CompletableFuture unsubscribeByFilter( String filter, TopicSelector topics); /** * Unsubscribe sessions that satisfy a given session filter from topics. * *

* This is equivalent to calling * {@link #unsubscribeByFilter(String, TopicSelector, SubscriptionByFilterCallback)} * with a selector parsed using {@link TopicSelectors#parse(String)}. * * @param filter the session filter expression * * @param topics the topics to unsubscribe specified as a * {@link TopicSelector} expression * * @param callback provides callback methods indicating the status of this * operation * * @throws IllegalArgumentException if {@code topics} is not a valid * selector expression * * @since 5.6 * * @deprecated since 6.7 *

* Methods that use callbacks are deprecated and will be removed * in a future release. Use CompletableFuture variant instead. */ @Deprecated void unsubscribeByFilter( String filter, String topics, SubscriptionByFilterCallback callback) throws IllegalArgumentException; /** * Unsubscribe sessions that satisfy a given session filter from topics. * * @param filter the session filter expression * * @param topics the topics to unsubscribe from * * @param callback provides callback methods indicating the status of this * operation * * @since 5.6 * * @deprecated since 6.7 *

* Methods that use callbacks are deprecated and will be removed * in a future release. Use CompletableFuture variant instead. */ @Deprecated void unsubscribeByFilter( String filter, TopicSelector topics, SubscriptionByFilterCallback callback); /** * Unsubscribe sessions that satisfy a given session filter from topics. * *

* This is equivalent to calling * {@link #unsubscribeByFilter(String, TopicSelector, SubscriptionByFilterCallback)} * with a selector parsed using {@link TopicSelectors#parse(String)}. * * @param filter the session filter expression * * @param topics the topics to unsubscribe specified as a * {@link TopicSelector} expression * * @param context passed to the callback with the reply to allow requests * and replies to be correlated. The caller may use any convenient * object reference, including {@code null} * * @param callback provides callback methods indicating the status of this * operation * * @throws IllegalArgumentException if {@code topics} is not a valid * selector expression * * @param context object type * * @since 5.6 * * @deprecated since 6.7 *

* Methods that use callbacks are deprecated and will be removed * in a future release. Use CompletableFuture variant instead. */ @Deprecated void unsubscribeByFilter( String filter, String topics, C context, SubscriptionByFilterContextCallback callback) throws IllegalArgumentException; /** * Unsubscribe sessions that satisfy a given session filter from topics. * * @param filter the session filter expression * * @param topics the topics to unsubscribe from * * @param context passed to the callback with the reply to allow requests * and replies to be correlated. The caller may use any convenient * object reference, including {@code null} * * @param callback provides callback methods indicating the status of this * operation * * @param context object type * * @since 5.6 * * @deprecated since 6.7 *

* Methods that use callbacks are deprecated and will be removed * in a future release. Use CompletableFuture variant instead. */ @Deprecated void unsubscribeByFilter( String filter, TopicSelector topics, C context, SubscriptionByFilterContextCallback callback); /** * Callback interface for filtered subscriptions and unsubscriptions. * * @since 5.6 * * @deprecated since 6.7 *

* Methods that use callbacks are deprecated and will be removed * in a future release. Use CompletableFuture variant instead. */ @Deprecated interface SubscriptionByFilterCallback extends Callback { /** * Called to indicate successful processing of the request at the * server. * * @param numberSelected the number of sessions that satisfied the * filter and qualified for subscription/unsubscription. This * will be 0 if no sessions satisfied the filter. */ void onComplete(int numberSelected); /** * The filter was rejected. No sessions were subscribed/unsubscribed. * * @param errors the detail of why the filter was rejected */ void onRejected(Collection errors); /** * Default implementation of {@link SubscriptionByFilterCallback}. *

* This logs onComplete calls at 'debug' level and onRejected calls at * 'error' level. This method may be overridden to perform more specific * processing. */ class Default extends Callback.Default implements SubscriptionByFilterCallback { private static final Logger LOG = LoggerFactory .getLogger(SubscriptionByFilterCallback.Default.class); @Override public void onComplete(int numberSelected) { LOG.debug( "{} - Subscription/Unsubscription complete : {} sessions selected", this, numberSelected); } @Override public void onRejected(Collection errors) { LOG.error( "{} - Subscription/Unsubscription rejected : {}", this, errors); } } } /** * Callback interface for filtered subscriptions and unsubscriptions that * have an associated context. * * @since 5.6 * @param the context object type * * @deprecated since 6.7 *

* Methods that use callbacks are deprecated and will be removed * in a future release. Use CompletableFuture variant instead. */ @Deprecated interface SubscriptionByFilterContextCallback extends ContextCallback { /** * Called to indicate successful processing of the request at the * server. * * @param context the context object the application supplied when * making the call; may be {@code null} * * @param numberSelected the number of sessions that satisfied the * filter and qualified for subscription/unsubscription. This * will be 0 if no sessions satisfied the filter. */ void onComplete(C context, int numberSelected); /** * The filter was rejected. No sessions were subscribed/unsubscribed. * * @param context the context object supplied when making the call * * @param errors the detail of why the filter was rejected */ void onRejected(C context, Collection errors); /** * Default implementation of {@link SubscriptionByFilterContextCallback} * . *

* This logs onComplete calls at 'debug' level and onRejected calls at * 'error' level. This method may be overridden to perform more specific * processing. * * @param context object type */ class Default extends ContextCallback.Default implements SubscriptionByFilterContextCallback { private static final Logger LOG = getLogger(SubscriptionByFilterContextCallback.Default.class); @Override public void onComplete(C context, int numberSelected) { LOG.debug( "{} - Subscription/Unsubscription complete : {} sessions selected, Context={}", this, numberSelected, context); } @Override public void onRejected(C context, Collection errors) { LOG.error( "{} - Subscription/Unsubscription rejected : {}, Context={}", this, errors, context); } } } /** * A single request from a session to subscribe to routing topic. * *

* Each request received by a handler must either be {@link #route routed} * or {@link #defer deferred}. * * @deprecated since 6.7 *

* Routing topics are deprecated. The more powerful * {@link SessionTrees} feature should be used in their place. */ @Deprecated interface RoutingSubscriptionRequest { /** * Identifies the session making the subscription request. * * @return the session id of the requesting session */ SessionId getSessionId(); /** * Identifies the subscribed routing topic. * * @return the topic path of the routing topic */ String getTopicPath(); /** * Defer the handling of this subscription request. * *

* When a request is deferred, the server will discard the request, and * the requesting session will not receive a subscription notification. * *

* An implementation can retain the requesting session's * {@link #getSessionId() session ID} and the routing topic's * {@link #getTopicPath() path} so a routing subscription can be * established at a later time using * {@link SubscriptionControl#subscribe(SessionId, String, SubscriptionCallback)}. * *

* A {@code RoutingSubscriptionRequest} can be used once. If * {@code route()} or {@code defer()} has already been called for this * {@code RoutingSubscriptionRequest}, calling this method will cause a * warning to be logged by the server, but otherwise have no effect. * *

Behavior since 6.0

* *

* From 6.0, this method returns a CompletableFuture and no longer * throws exceptions. All errors are reported through the * CompletableFuture result. * * @return a CompletableFuture that completes when the server has * processed the defer instruction. * *

* If the instruction was processed, the CompletableFuture will * complete successfully. The result type is any rather than * Void to provide forward compatibility with future iterations * of this API that may provide a non-null result with a more * specific result type. * *

* Otherwise, the CompletableFuture will complete exceptionally * with a {@link CompletionException}. Common reasons for * failure, listed by the exception reported as the * {@link CompletionException#getCause() cause}, include: * *

    *
  • {@link SessionException} – if {@code route()} or * {@code defer()} has already been called for this * {@code RoutingSubscriptionRequest}; * *
  • {@link SessionClosedException} – if the session is * closed. *
*/ CompletableFuture defer(); /** * Resolve a subscription request by providing the path of a source * topic to which the requesting session will be subscribed via the * routing topic. * *

* The requesting session will receive a subscription notification with * the routing topic's path and the topic specification of the source * topic. If the source topic is stateful, the requesting session will * also be sent an update for the routing topic path with the current * value of the source topic. The existence of the source topic is * hidden from the requesting session. Updates to the source topic are * forwarded to the session as if they came from the routing topic. * *

* A session that does not have {@code SELECT_TOPIC} or * {@code READ_TOPIC} permission for the source topic cannot subscribe * directly, but can be subscribed indirectly using this method. * * @param topicPath the topic path of the source topic * @return a CompletableFuture that completes when the server has * processed the routing instruction. * *

* If a routing subscription was established, the * CompletableFuture will complete successfully. The result type * is any rather than Void to provide forward compatibility * with future iterations of this API that may provide a * non-null result with a more specific result type. * *

* Otherwise, the CompletableFuture will complete exceptionally * with a {@link CompletionException}. Common reasons for * failure, listed by the exception reported as the * {@link CompletionException#getCause() cause}, include: * *

    *
  • {@link RoutingSubscriptionException} – if there is * no topic bound to {@code topicPath}; * *
  • {@link RoutingSubscriptionException} – if the topic * bound to {@code topicPath} is itself a routing topic; * *
  • {@link PermissionsException} – if the calling * session does not have {@code READ_TOPIC} permission for the * source topic bound to {@code topicPath}; * *
  • {@link PermissionsException} – if the calling * session does not have {@code READ_TOPIC} permission for the * routing topic bound to {@link #getTopicPath()}; * *
  • {@link SessionException} – if {@code route()} or * {@code defer()} has already been called for this * {@code RoutingSubscriptionRequest}; * *
  • {@link SessionClosedException} – if the session is * closed. *
*/ CompletableFuture route(String topicPath); /** * Resolve a subscription request by providing the path of a source * topic to which the requesting session will be subscribed via the * routing topic. * *

* The requesting session will receive a subscription notification with * the routing topic's path and the topic specification of the source * topic. If the source topic is stateful, the requesting session will * also be sent an update for the routing topic path with the current * value of the source topic. The existence of the source topic is * hidden from the requesting session. Updates to the source topic are * forwarded to the session as if they came from the routing topic. * *

* A session that does not have {@code SELECT_TOPIC} or * {@code READ_TOPIC} permission for the source topic cannot subscribe * directly, but can be subscribed indirectly using this method. * *

* The operation will fail and the callback with be * {@link SubscriptionCallback#onDiscard() discarded} in the following * cases: * *

    *
  • There is no source topic bound to {@code topicPath}; *
  • The topic bound to {@code topicPath} is a routing topic; *
  • The calling session does not have {@code READ_TOPIC} permission * for the source topic bound to {@code topicPath}; *
  • The calling session does not have {@code READ_TOPIC} permission * for the routing topic bound to {@link #getTopicPath()}; *
  • {@code route()} or {@code defer()} has already been called for * this {@code RoutingSubscriptionRequest}. *
* * @param topicPath the topic path of the resolved source topic * * @param callback provides callback methods indicating the status of * this request. */ void route(String topicPath, SubscriptionCallback callback); /** * Provide the path of a source topic to which the requesting session * will be subscribed via the routing topic, with a contextual object. * *

* The requesting session will receive a subscription notification with * the routing topic's path and the topic specification of the source * topic. If the source topic is stateful, the requesting session will * also be sent an update for the routing topic path with the current * value of the source topic. The existence of the source topic is * hidden from the requesting session. Updates to the source topic are * forwarded to the session as if they came from the routing topic. * *

* A session that does not have {@code SELECT_TOPIC} or * {@code READ_TOPIC} permission for the source topic cannot subscribe * directly, but can be subscribed indirectly using this method. * *

* The operation will fail and the callback with be * {@link SubscriptionCallback#onDiscard() discarded} in the following * cases: * *

    *
  • There is no source topic bound to {@code topicPath}; *
  • The topic bound to {@code topicPath} is a routing topic; *
  • The calling session does not have {@code READ_TOPIC} permission * for the source topic bound to {@code topicPath}; *
  • The calling session does not have {@code READ_TOPIC} permission * for the routing topic bound to {@link #getTopicPath()}; *
  • {@code route()} or {@code defer()} has already been called for * this {@code RoutingSubscriptionRequest}. *
* * @param topicPath the topic path of the resolved source topic * * @param context passed to the callback with the reply to allow * requests and replies to be correlated. The caller may use any * convenient object reference, including {@code null} * * @param callback provides callback methods indicating the status of * this request. * * @param context object type */ void route( String topicPath, C context, SubscriptionContextCallback callback); /** * Handler for routing subscription requests. * * @deprecated since 6.7 *

* Routing topics are deprecated. The more powerful * {@link SessionTrees} feature should be used in their * place. */ @Deprecated interface RoutingHandler extends Stream { /** * A request to subscribe to a specific routing topic. * * @param request the request, which must be replied to or deferred */ void onSubscriptionRequest(RoutingSubscriptionRequest request); /** * Abstract handler implementation. *

* The * {@link RoutingHandler#onSubscriptionRequest(SubscriptionControl.RoutingSubscriptionRequest) * onSubscriptionRequest} method must be implemented. */ abstract class Default extends Stream.Default implements RoutingHandler { } } /** * Handler for routing subscription requests registered with the older, * callback-based * {@link SubscriptionControl#addRoutingSubscriptionHandler(String, SubscriptionControl.RoutingSubscriptionRequest.Handler) * addRoutingSubscriptionHandler(String, Handler)} method. * * @deprecated since 6.7 *

* Routing topics are deprecated. The more powerful * {@link SessionTrees} feature should be used in their * place. */ @Deprecated interface Handler extends TopicTreeHandler { /** * A request to subscribe to a specific routing topic. * * @param request the request, which must be replied to or deferred */ void onSubscriptionRequest(RoutingSubscriptionRequest request); /** * Abstract handler implementation. *

* The * {@link Handler#onSubscriptionRequest(SubscriptionControl.RoutingSubscriptionRequest) * onSubscriptionRequest} method must be implemented. */ abstract class Default extends TopicTreeHandler.Default implements Handler { } } } /** * Result used by CompletableFuture variants of * {@link SubscriptionControl#subscribeByFilter(String, String) * subscribeByFilter} and * {@link SubscriptionControl#unsubscribeByFilter(String, String) * unsubscribeByFilter}. * * @since 6.0 */ public interface SubscriptionByFilterResult { /** * @return number of sessions that satisfied the filter and qualified * for subscription/unsubscription. This will be 0 if no * sessions satisfied the filter. */ int numberSelected(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy