public interface TopicControl extends Feature
1) Adding and removing topics.
2) Missing topic notifications — listening for requests to subscribe to (or
fetch†) topics that do not exist thus allowing dynamic topic creation on
demand.
3) Topic event listeners — listening for topic events, such as the number of
subscribers to a topic changing from zero to greater than zero or from
greater than zero to zero.
† Missing topic notifications only occur when using the deprecated
Topics.fetch(com.pushtechnology.diffusion.client.topics.TopicSelector, com.pushtechnology.diffusion.client.features.Topics.FetchStream)
mechanism. The newer Topics.fetchRequest()
mechanism does not generate missing topic notifications.
The Diffusion server stores data in topics. Each topic is bound to a topic
path in the topic tree, and may have a current value. Sessions can subscribe
to topics. Updates to topic values are broadcast to subscribing sessions.
There are several types of topic. The topic type
determines
the type of the data values a topic publishes to subscribers.
The simplest way to create a topic is to call
addTopic(String, TopicType)
, supplying a topic type. For example, to
create a JSON
topic bound to the topic path
foo
:
CompletableFuture<AddTopicResult%gt; result = topicControl.addTopic("foo", TopicType.JSON);
Success or failure is reported asynchronously through the CompletableFuture result.
The nature of a topic depends primarily on its topic type, but can be
customized using topic properties. Some types of topic cannot be created
without supplying mandatory topic properties. Topic properties can be
supplied in a topic specification
using
addTopic(String, TopicSpecification, AddCallback)
. Topic
specifications can be created using newSpecification(TopicType)
and
further customized with builder methods. For example, to create a
JSON
topic bound to the topic path foo
with
the VALIDATE_VALUES
property set
to true
:
CompletableFuture<AddTopicResult> result = topicControl.addTopic( "foo", topicControl.newSpecification(TopicType.JSON) .withProperty(TopicSpecification.VALIDATE_VALUES, "true"));
See TopicSpecification
for details of the available topic properties
and their effects on the different types of topic.
Topic creation is idempotent. If addTopic(path, specification)
is called and there is already a topic bound
to path
with a topic specification equal to specification
,
the call will complete normally with an TopicControl.AddTopicResult.EXISTS
result.
However, if there is a topic bound to path
with a different topic
specification, the call will complete exceptionally with an
TopicControl.ExistingTopicException
.
Topics can be removed using removeTopics(TopicSelector)
. Only those
selected topics that the caller has MODIFY_TOPIC
permission to will be removed, any others will remain.
Topics can also be automatically removed according to a removal criteria
specified using the REMOVAL
topic
property.
A topic can be bound to any path in the topic tree namespace. The only restriction is that two topics can not have the same path.
In the following example a topic can be created with the path A/B/foo
even though there are no topics with path A
or A/B
:
topicControl.addTopic("A/B/foo", TopicType.JSON);
Topics bound to the paths A
or A/B
can be created later.
Topics can be removed without affecting the topics subordinate to them in the
topic tree using remove(java.lang.String, com.pushtechnology.diffusion.client.features.control.topics.TopicControl.RemovalCallback)
providing a path topic selector. By using
the //
topic selector qualifier it is possible to remove a topic and
all of its descendant topics, that is to remove whole topic tree branches.
To add or remove a topic, a session needs MODIFY_TOPIC
permission for the topic path. When removing topics with a
topic selector that matches more than one topic, only topics with paths for
which the session has MODIFY_TOPIC
permission will be removed.
To register a
missing topic handler
or a
topic event listener
the session needs REGISTER_HANDLER
permission.
This feature may be obtained from a session
as follows:
TopicControl topicControl = session.feature(TopicControl.class);
Modifier and Type | Interface and Description |
---|---|
static interface |
TopicControl.AddCallback
Callback interface for adding topics when no context is provided.
|
static interface |
TopicControl.AddContextCallback<C>
Contextual callback interface for adding topics.
|
static class |
TopicControl.AddTopicException
Exception thrown to report a failure to add a topic.
|
static class |
TopicControl.AddTopicResult
Used to report the result of adding a topic.
|
static class |
TopicControl.ExistingTopicException
Exception thrown to report a topic could not be added because an existing
topic with a different specification is bound to the topic path.
|
static class |
TopicControl.IncompatibleExistingTopicException
Exception thrown to report that a topic exists at the same path that is
managed by a component that has exclusive control over the topic.
|
static class |
TopicControl.IncompatibleMasterTopicException
Deprecated.
since 6.4
Slave topics are deprecated. Since 6.5, this exception is no longer used. This exception will be removed in a future release. |
static class |
TopicControl.IncompatibleParentTopicException
Deprecated.
since 6.5
Since 6.5, this exception is no longer used. This exception will be removed in a future release. |
static class |
TopicControl.IncompatibleTopicException
Exception thrown to report a topic could not be added because there is an
existing topic that is incompatible with the request.
|
static class |
TopicControl.InvalidTopicPathException
Exception thrown to report a topic could not be added because the topic
path supplied is invalid.
|
static class |
TopicControl.InvalidTopicSpecificationException
Exception thrown to report a topic could not be added because the
specification is invalid.
|
static interface |
TopicControl.MissingTopicHandler
Handler called when a session subscribes (or fetches†) using a topic
selector that matches no topics.
|
static interface |
TopicControl.MissingTopicNotification
Notification that a session has made a subscription (or fetch†) request
using a selector that does not match any topics.
|
static interface |
TopicControl.MissingTopicNotificationStream
Stream called when a session subscribes (or fetches†) using a topic
selector that matches no topics.
|
static interface |
TopicControl.RemovalCallback
Callback interface for
remove requests when
no context is used. |
static interface |
TopicControl.RemovalContextCallback<C>
Contextual callback interface for
remove requests. |
static interface |
TopicControl.TopicEventListener
Deprecated.
Since 6.1
See
|
static interface |
TopicControl.TopicEventStream
Deprecated.
Since 6.1
See
|
static class |
TopicControl.TopicLicenseLimitException
Exception thrown to report a topic could not be added because a license
limit has been exceeded.
|
Modifier and Type | Method and Description |
---|---|
void |
addMissingTopicHandler(String topicPath,
TopicControl.MissingTopicHandler handler)
Register a
TopicControl.MissingTopicHandler to handle requests for a branch of
the topic tree. |
CompletableFuture<Registration> |
addMissingTopicHandler(String topicPath,
TopicControl.MissingTopicNotificationStream handler)
Register a
TopicControl.MissingTopicNotificationStream to handle requests for
a branch of the topic tree. |
CompletableFuture<TopicControl.AddTopicResult> |
addTopic(String topicPath,
TopicSpecification specification)
Request creation of a topic.
|
<C> void |
addTopic(String topicPath,
TopicSpecification specification,
C context,
TopicControl.AddContextCallback<C> callback)
Version of
addTopic(String, TopicSpecification, AddCallback)
that allows a user defined context to be provided. |
void |
addTopic(String topicPath,
TopicSpecification specification,
TopicControl.AddCallback callback)
Send a request to the server to add a topic.
|
CompletableFuture<TopicControl.AddTopicResult> |
addTopic(String topicPath,
TopicType topicType)
Request creation of a topic.
|
void |
addTopicEventListener(String topicPath,
TopicControl.TopicEventListener listener)
Deprecated.
since 6.1
The main use case for this method is the removal of unused
topics, now much better satisfied by the
|
CompletableFuture<Registration> |
addTopicEventListener(String topicPath,
TopicControl.TopicEventStream listener)
Deprecated.
since 6.1
The main use case for this method is the removal of unused
topics, now much better satisfied by the
|
TopicSpecification |
newSpecification(TopicType topicType)
Create a new
TopicSpecification for a given topic type. |
<C> void |
remove(String topicSelector,
C context,
TopicControl.RemovalContextCallback<C> callback)
Version of
remove(String, RemovalCallback) that allows a user
defined context to be provided. |
void |
remove(String topicSelector,
TopicControl.RemovalCallback callback)
Send a request to remove one or more topics.
|
CompletableFuture<?> |
removeTopics(String topicSelector)
Send a request to remove one or more topics.
|
CompletableFuture<?> |
removeTopics(TopicSelector topicSelector)
Send a request to remove one or more topics.
|
getSession
TopicSpecification newSpecification(TopicType topicType)
TopicSpecification
for a given topic type.
In Diffusion 6.2, a factory method for creating topic specifications
was added to the Diffusion
enum.
Diffusion.newTopicSpecification
can be imported with a static import, and should be preferred over this
method.
topicType
- the topic typewithProperty
or
withProperties
methods of the provided specification.CompletableFuture<TopicControl.AddTopicResult> addTopic(String topicPath, TopicType topicType)
This is a convenience method that is equivalent to:
topicControl.addTopic( topicPath, topicControl.newSpecification(topicType));
topicPath
- the topic path to which the topic will be boundtopicType
- the type of topic to be created
If the task completes successfully, the CompletableFuture result
will be indicate whether a new topic was created, or whether a
topic with an identical topic specification is already bound to
at topicPath
.
Otherwise, the CompletableFuture will complete exceptionally with
a CompletionException
. Common reasons for failure, listed
by the exception reported as the
cause
, include:
TopicControl.ExistingTopicException
– a topic is bound to
topicPath
with a different topic specification;
TopicControl.IncompatibleExistingTopicException
– an
incompatible topic already exists at topicPath
;
TopicControl.IncompatibleParentTopicException
– a topic
could not be added because a topic at a parent path is
incompatible;
TopicControl.InvalidTopicPathException
– topicPath
is not a valid topic path;
TopicControl.InvalidTopicSpecificationException
– the
specification is invalid, possibly because mandatory properties
not supplied;
TopicControl.TopicLicenseLimitException
– the topic could
not be added as it would breach a licensing limit;
ClusterRoutingException
– if the operation failed
due to a transient cluster error;
TopicControl.AddTopicException
– the topic could not be
created for some reason other than those specified above;
SessionSecurityException
– the calling session
does not have MODIFY_TOPIC
permission for
topicPath
;
SessionClosedException
– the session is closed.
CompletableFuture<TopicControl.AddTopicResult> addTopic(String topicPath, TopicSpecification specification)
topicPath
- the topic path to which the topic will be boundspecification
- defines the topic to be created. A specification can
be created using newSpecification(TopicType)
.
If the task completes successfully, the CompletableFuture result
will be indicate whether a new topic was created, or whether a
topic with an identical topic specification is already bound to
at topicPath
.
Otherwise, the CompletableFuture will complete exceptionally with
a CompletionException
. Common reasons for failure, listed
by the exception reported as the
cause
, include:
TopicControl.ExistingTopicException
– a topic is bound to
topicPath
with a different topic specification;
TopicControl.IncompatibleExistingTopicException
– an
incompatible topic already exists at topicPath
;
TopicControl.IncompatibleMasterTopicException
– a slave
topic could not be added because the topic at the master path is
incompatible;
TopicControl.IncompatibleParentTopicException
– a topic
could not be added because a topic at a parent path is
incompatible;
TopicControl.InvalidTopicPathException
– topicPath
is not a valid topic path;
TopicControl.InvalidTopicSpecificationException
– the
specification is invalid;
TopicControl.TopicLicenseLimitException
– the topic could
not be added as it would breach a licensing limit;
ClusterRoutingException
– if the operation failed
due to a transient cluster error;
TopicControl.AddTopicException
– the topic could not be
created for some reason other than those specified above;
SessionSecurityException
– the calling session
does not have MODIFY_TOPIC
permission for
topicPath
;
SessionClosedException
– the session is closed.
<C> void addTopic(String topicPath, TopicSpecification specification, C context, TopicControl.AddContextCallback<C> callback)
addTopic(String, TopicSpecification, AddCallback)
that allows a user defined context to be provided.C
- the context object typetopicPath
- the topic path to which the topic will be boundspecification
- defines the topic to be created. A specification can
be created using newSpecification(TopicType)
.context
- an object passed to the callback with the reply to allow
requests and replies to be correlated. The caller may use any
convenient object reference, including null
callback
- called with the resultvoid addTopic(String topicPath, TopicSpecification specification, TopicControl.AddCallback callback)
topicPath
- the topic path to which the topic will be boundspecification
- defines the topic to be created. A specification can
be created using newSpecification(TopicType)
.callback
- called with the resultCompletableFuture<?> removeTopics(TopicSelector topicSelector)
All topics that match the provided topicSelector
that the caller
has permission to remove will be removed.
The selector's descendant pattern qualifier
(a
trailing /
or //
), can be used to remove descendant
topics. If a single /
qualifier is specified, all descendants of
the matched topic paths will be removed. If //
is specified, the
matched paths and all descendants of the matched paths (complete
branches) will be removed.
topicSelector
- specifies the topics to removeIf the task completes successfully, the CompletableFuture result will be null. 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 CompletionException
. Common reasons for failure, listed
by the exception reported as the
cause
, include:
SessionClosedException
– the session is closed.
CompletableFuture<?> removeTopics(String topicSelector) throws IllegalArgumentException
This is equivalent to calling removeTopics(TopicSelector)
with a
selector parsed using TopicSelectors.parse(String)
.
topicSelector
- a topic selector expression
specifying the topics to remove.If the task completes successfully, the CompletableFuture result will be null. 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 CompletionException
. Common reasons for failure, listed
by the exception reported as the
cause
, include:
SessionClosedException
– the session is closed.
IllegalArgumentException
- if topicSelector
is an invalid
topic selector expressionvoid remove(String topicSelector, TopicControl.RemovalCallback callback) throws IllegalArgumentException
All topics that match the provided topicSelector
that the caller
has permission to remove will be removed.
The selector's descendant pattern qualifier
(a
trailing /
or //
), can be used to remove descendant
topics. If a single /
qualifier is specified, all descendants of
the matched topic paths will be removed. If //
is specified, the
matched paths and all descendants of the matched paths (complete
branches) will be removed.
topicSelector
- a topic selector expression
specifying the topics to removecallback
- called to notify request completedIllegalArgumentException
- if topicSelector
is an invalid
topic selector expression<C> void remove(String topicSelector, C context, TopicControl.RemovalContextCallback<C> callback) throws IllegalArgumentException
remove(String, RemovalCallback)
that allows a user
defined context to be provided.C
- the context object typetopicSelector
- a topic selector expression
specifying the topics to removecontext
- an object passed to the callback with the reply to allow
requests and replies to be correlated. The caller may use any
convenient object reference, including null
callback
- called to notify request completedIllegalArgumentException
- if topicSelector
is an invalid
topic selector expressionCompletableFuture<Registration> addMissingTopicHandler(String topicPath, TopicControl.MissingTopicNotificationStream handler)
TopicControl.MissingTopicNotificationStream
to handle requests for
a branch of the topic tree.
The provided handler is called when a session subscribes (or fetches†)
using a topic selector that matches no existing topics. This allows a
control client session to intercede when another session requests a topic
that does not exist. The control client may use any of the
addTopic
methods to create the topic, take some other action, or
do nothing, before allowing the client operation to proceed by calling
proceed()
. Alternatively, the
control client can call cancel()
to discard the request.
A session can register multiple handlers, but may only register a single
handler for a given topic path. If there is already a handler registered
for the topic path the operation will fail with a
HandlerConflictException
. A handler will only be called for topic
selectors with a path prefix
that
starts with or is equal to topicPath
. If the path prefix matches
multiple handlers, the one registered for the most specific (longest)
topic path will be called.
Prefer this method to the callback-based alternative
addMissingTopicHandler(String, MissingTopicHandler)
since it
provides better error reporting.
† Missing topic notifications only occur when using the deprecated
Topics.fetch(com.pushtechnology.diffusion.client.topics.TopicSelector, com.pushtechnology.diffusion.client.features.Topics.FetchStream)
mechanism. The newer Topics.fetchRequest()
mechanism does not generate missing topic notifications.
topicPath
- identifies a branch of the topic treehandler
- the handler to use for routing topics at or below the
topicPath
(unless there is a handler registered for a more
specific topic path)
If registration was successful, the CompletableFuture will
complete successfully with a Registration
which can be
used to unregister the handler.
Otherwise, the CompletableFuture will complete exceptionally with
a CompletionException
. Common reasons for failure, listed
by the exception reported as the
cause
, include:
HandlerConflictException
– if the session has
already registered a missing topic handler for topicPath
;
SessionSecurityException
– if the session does
not have REGISTER_HANDLER
permission;
SessionClosedException
– if the session is
closed.
void addMissingTopicHandler(String topicPath, TopicControl.MissingTopicHandler handler)
TopicControl.MissingTopicHandler
to handle requests for a branch of
the topic tree.
Prefer the CompletableFuture-based alternative
addMissingTopicHandler(String, MissingTopicNotificationStream)
since it provides better error reporting.
The provided handler is called when a session subscribes (or fetches†)
using a topic selector that matches no existing topics. This allows a
control client session to intercede when another session requests a topic
that does not exist. The control client may use any of the
addTopic
methods to create the topic, take some other action, or
do nothing, before allowing the client operation to proceed by calling
proceed()
. Alternatively, the
control client can call cancel()
to discard the request.
A session can register multiple handlers, but may only register a single
handler for a given topic path. See
onActive
.
A handler will only be called for topic selectors with a
path prefix
that starts with or is
equal to topicPath
. If the path prefix matches multiple handlers,
the one registered for the most specific (longest) topic path will be
called.
† Missing topic notifications only occur when using the deprecated
Topics.fetch(com.pushtechnology.diffusion.client.topics.TopicSelector, com.pushtechnology.diffusion.client.features.Topics.FetchStream)
mechanism. The newer Topics.fetchRequest()
mechanism does not generate missing topic notifications.
topicPath
- identifies a branch of the topic treehandler
- the handler to use for routing topics at or below the
topicPath
(unless there is a handler registered for a more
specific topic path)@Deprecated CompletableFuture<Registration> addTopicEventListener(String topicPath, TopicControl.TopicEventStream listener)
The main use case for this method is the removal of unused
topics, now much better satisfied by the
REMOVAL
topic property,
using the 'subscriptions < n for' condition. This method
only takes into account local sessions. The REMOVAL topic
property is fully cluster aware. This method will be removed
in a future release.
TopicControl.TopicEventStream
to receive topic events for a branch
of the topic tree.
Events are emitted when a topic is subscribed to by one or more sessions after previously having no subscribers and when a topic is no longer subscribed to by any session. These events are averaged over a small window of time to prevent rapid dispatch of events that ultimately return a topic to its previous state.
Prefer this method to the callback-based alternative
addTopicEventListener(String, TopicEventListener)
since it
provides better error reporting.
This mechanism only works for a single server configuration and not across a cluster.
topicPath
- a full path identifying a branch of the topic treelistener
- specifies the listener for the specified branch (unless
overridden by a listener registered against a more specific
branch)
If registration was successful, the CompletableFuture will
complete successfully with a Registration
which can be
used to unregister the handler.
Otherwise, the CompletableFuture will complete exceptionally with
a CompletionException
. Common reasons for failure, listed
by the exception reported as the
cause
, include:
HandlerConflictException
– if the session has
already registered a topic event listener for topicPath
;
SessionSecurityException
– if the session does
not have REGISTER_HANDLER
permission;
SessionClosedException
– if the session is
closed.
@Deprecated void addTopicEventListener(String topicPath, TopicControl.TopicEventListener listener)
The main use case for this method is the removal of unused
topics, now much better satisfied by the
REMOVAL
topic property,
using the 'subscriptions < n for' condition. This method
only takes into account local sessions. The REMOVAL topic
property is fully cluster aware. This method will be removed
in a future release.
TopicControl.TopicEventListener
to receive topic events for a
branch of the topic tree.
Prefer the CompletableFuture-based alternative
addTopicEventListener(String, TopicEventStream)
since it
provides better error reporting.
Events are emitted when a topic is subscribed to by one or more sessions after previously having no subscribers and when a topic is no longer subscribed to by any session. These events are averaged over a small window of time to prevent rapid dispatch of events that ultimately return a topic to its previous state.
This mechanism only works for a single server configuration and not across a cluster.
topicPath
- a full path identifying a branch of the topic treelistener
- specifies the listener for the specified branch (unless
overridden by a listener registered against a more specific
branch)Copyright © 2020 Push Technology Ltd. All Rights Reserved.