Interface ITopicViews
This feature allows a client session to manage topic views.
Inherited Members
Namespace: PushTechnology.ClientInterface.Client.Features
Assembly: Diffusion.Client.dll
Syntax
public interface ITopicViews : IFeature
Remarks
A topic view maps one part of the server's topic tree to another. It dynamically creates a set of reference topics from a set of source topics, based on a declarative topic view specification. The capabilities of topic views range from simple mirroring of topics within the topic tree to advanced capabilities that include publication of partial values and throttling the rate of publication.
Each reference topic has a single source topic and has the same topic type as its source topic. Reference topics are read-only (they cannot be updated), nor can they be created or removed directly. Otherwise, they behave just like standard topics. A client session can subscribe to a reference topic, and can fetch the reference topic's current value if it has one.
The source topics of a topic view are defined by a topic selector. A reference topic is created for each source topic, according to the topic view. If a source topic is removed, reference topics that are derived from it will automatically be removed. If a topic is added that matches the source topic selector of a topic view, a corresponding reference topic will be created. Removing a topic view will remove all of its reference topics.
Topic view specifications
The following is a simple topic view specification that mirrors all topics
below the path a
to reference topics below the path
b
.
map ?a// to b/<path(1)>
A topic view with this specification will map a source topic at the path
a/x/y/z
to a reference topic at the path b/x/y/z
.
The specification is simple, so the reference topic will exactly mirror the
source topic.
A general topic view specification comprises several parts:
- The source topic clause identifies the source topics.
- The path mapping clause determines how reference topic paths are derived from the source topic paths.
- The optional topic property mapping clause determines how reference topic properties are derived from source topic properties.
- The optional value mapping clause determines how reference topic values are derived from source topic values.
- The optional throttle clause constrains the rate at which each reference topic is updated when its source topic is updated.
The source topic clause begins with the map
keyword and is followed
by a topic selector. These topic selectors follow the same parsing rules
as other topic selectors.
When evaluating a topic view, topics in the topic tree that match the source topic selector are considered, with the following exceptions:
- Topics created through the Publisher API;
ROUTING
topics.
Both SLAVE
and reference topics are valid source
topics. In particular, chaining of topic views is supported; that is, a
reference topic created by one topic view can be the source topic of another
topic view. Additionally, a reference topic can be the master topic of a
slave topic, or the source topic of a routing topic subscription.
Prefer topic views to slave topics. Individual topics can be mirrored by creating a slave topic, but maintaining slave topics for a branch of the topic tree quickly becomes tedious. A topic view will maintain such a branch automatically, and provides more sophisticated mapping options.Path mapping clause
The path of a reference topic is derived from the source topic according to the topic view path mapping. The path mapping allows the source topic path and the value of the source topic to determine the path of the reference topic.
A path mapping clause begins with the to
keyword and is followed by a
path mapping template. A path mapping template is a topic path with embedded
directives. Directives are evaluated when creating the topic
reference and substituted into the topic path. Directives are delimited by
angle brackets <
, >
and consist of the name of the
directive and a list of parameters. The parameter list is comma-separated and
surrounded by parentheses ((
, )
).
Two path mapping directives are supported:
- Source path directives
- Source path directives extract a portion of the source path and are
parameterized by the index of the start part of the source path and the
number of parts to include. The number of parts parameter is optional – if it
is missing, the selection extends to the end of the source path. The syntax is
<path(start, number)>
, or<path(start)>
when the number of parts parameter is omitted. For example, given the source patha/b/c/d
, the source path directive<path(1, 2)>
is mapped to the reference topic pathb/c
, and the source path directive<path(2)>
is mapped to the reference topic pathc/d
. - Source value directives
- Source value directives are only applied to
JSON
source topics; if the path mapping contains a source value directive, non-JSON topics matching the source topic selector are ignored. Source value directives use the keywordscalar
and are parameterized by a single JSON pointer that extracts a scalar value from the source value. A scalar value is a string, a number,true
,false
, ornull
, that is, anything other than an array or a object. If the JSON pointer does not refer to a scalar value in the source value, no reference topic will be created. This includes the cases where the JSON pointer refers to an array or an object), or when no part of the source value is selected.
Deriving the reference topic paths from part of the source topic value effectively creates a secondary index on the value. For source value directives to work efficiently, the selected scalar values should be relatively stable. If an update to the source topic changes the selected scalar value, the corresponding reference topic will be removed and a new reference topic will be created.
For example, given a source value of
{
"account" : "1234",
"balance" : { "amount" : 12.57, "currency" : "USD" }
}
and the source value directive
currency/<scalar(/balance/currency)>/account/<scalar(/account)>
, the
reference topic path will be currency/USD/account/1234
.
If the extracted value is a string, it is copied literally to the reference
topic path. A value that contain path separators (/
) will create a
reference topic path with levels than the path mapping template.
An extracted value of null
will be copied to the reference topic path
as the string "null"
.
Topic property mapping clause
The TopicSpecification
of a reference topic is
derived from the topic specification of the source topics. A reference topic
has the same topic type as its source topic.
The topic properties of a reference topic are derived from the source topic.
Some topic properties can be tuned using the optional topic property mapping
clause. The following table describes the behavior for each topic property.
Source topic property | Reference topic specification default | Can be set by topic property mapping? | Notes |
---|---|---|---|
Compression | Copied from source topic specification | Yes | |
Conflation | Copied from source topic specification | Yes | |
DontRetainValue | Copied from source topic specification | Yes | |
Owner | Not set | No | |
Persistent | Not set | No | Reference topics are not persisted. Topic views are persisted, so a reference topic will be recreated on server restart if its source is persistent. |
PublishValuesOnly | Copied from source topic specification | Yes | |
Removal | Not set | No | Reference topics cannot be removed directly. |
Schema | Copied from source topic specification | No | A RECORD_V2 reference topic has the same schema as its source topic. |
SlaveMasterTopic | Not set | No | If a reference topic has a slave topic as its source topic, it indirectly references the slave's master topic. |
TidyOnUnsubscribe | Copied from source topic specification | Yes | |
TimeSeriesEventValueType | Copied from source topic specification | No | A PushTechnology.ClientInterface.Client.Features.TimeSeries reference topic has the same value type as its source topic. |
TimeSeriesRetainedRange | Copied from source topic specification | Yes, with restrictions | A topic property mapping cannot increase the time series retained range
by overriding the TIME_SERIES_RETAINED_RANGE property. The retained
range of a reference time series topic will be constrained to be no greater
than that of its source topic. |
TimeSeriesSubscriptionRange | Copied from source topic specification | Yes | |
ValidateValues | Not set | No | A reference topic reflects updates to its source topic. It cannot reject updates. |
A topic property mapping clause begins with the keywords
with properties
and consists of a comma-separated list of topic
property keys and values, each separated by a colon. For example, the
following topic view specification maps all topics below the path
a
to reference topics below the path b
, and
disables both conflation and compression for the reference topics.
map ?a// to b/<path(1)> with properties 'CONFLATION':'off', 'COMPRESSION':'false'
Topic value mapping
The value of a reference topic is derived from the source topic according to the topic view value mapping. By default, a reference topic's value is the same as its source topic.
For JSON
source topics, the optional topic value mapping
clause can be used to extract part of the source value. A topic value
mapping begins the keyword as
and is followed by a value directive.
A value directive is delimited by angle brackets (<
, >
),
and consists of the value
keywords and a single JSON pointer parameter.
The JSON pointer selects the part of the source value to copy.
For example, given a source value of
{
"account" : "1234",
"balance" : { "amount" : 12.57, "currency" : "USD" }
}
and the value mapping clause as <value(/balance)>
, the
reference topic value will be
{
"amount" : 12.57,
"currency" : "USD"
}
Topic value mappings are often used with path value mappings. For example:
map ?accounts// to balances/<scalar(/account)> as <value(/balance)>
Throttle clause
The optional throttle clause can be used to constrain the rate at which a reference topic is updated when its source topic is updated. The primary application of a throttle clause is to restrict the number of updates sent to reference topic subscribers, reducing network utilization or the processing each subscriber must do. Throttling also restricts the rate at which client sessions can observe changes to reference topic values using the fetch API.
The throttle clause has the form
throttle to X updates every period
, where
X is a positive integer, and period is a positive integer
followed by a time unit which is one of seconds
,
minutes
, or hours
.
For example, the following topic view specification maps all topics below the
path a
to reference topics below the path b
, but
updates the value of each reference topic at most twice every five seconds:
map ?a// to b/<path(1)> throttle to 2 updates every 5 seconds
To improve readability, the throttling clause allows 1 update
as
an alternative to 1 updates
, and every second
as an
alternative to every 1 seconds
(and so on, for other time
units). For example, the following topic view specification maps all topics
below the path a
to reference topics below the path
b
, but updates the value of each reference topic at most once
every hour:
map ?a// to b/<path(1)> throttle to 1 update every minute
The throttle clause is only applied when a source topic is updated more frequently than the configured rate. If a source topic is updated less frequently, updates are passed on unconstrained. If the rate is exceeded, a reference topic will not be updated again until the configured period has expired. At this time, the reference topic will be updated based on the source topic updates that happened in the interim, and a single value will be published. Thus, a throttle clause provides topic-scoped conflation.
The throttle clause is ignored for time series topics because time series updates do not support efficient conflation. Updates to source time series topics are passed on immediately to the corresponding reference topics, regardless of any throttle clause.
Quoting and white space
Topic selectors and path mapping templates can be quoted or unquoted. They are quoted using the single quote mark. To include whitespace, single quotes or literal opening angle brackets they must be quoted. In quoted selectors and templates single quotes, literal opening angle brackets and backslashes must be escaped with a single backslash. In templates the opening angle bracket should be unescaped when beginning a directive. Characters in unquoted selectors and templates can't be escaped.
Any whitespace can be used to separate keywords, statements and clauses.
Dealing with topic path conflicts
Reference topics have a lower priority than normal topics created through the API, including replicas of normal topics created by topic replication or fan-out. A reference topic will only be created if no topic or reference topic is already bound to its derived topic path.
Topic views have a precedence based on order of creation. If two topic views define mappings the same topic path, the earliest-created topic view will create a reference topic. If a topic view is updated, it retains its original precedence.
Topic view persistence and replication
Reference topics are neither replicated nor persisted. They are created and removed based on their source topics. However, topic views are replicated and persisted. A server that restarts will restore topic views during recovery. Each topic view will then create reference topics based on the source topics that have been recovered.
The server records all changes to topic views in a persistent store. Topic views are restored if the server is started.
If a server belongs to a cluster, topic views will be replicated to each server in the cluster. Topic views are evaluated locally within a server. Replicated topic views that select non-replicated source topics can create different reference topics on each server in the cluster.
Access control
The following access control restrictions are applied:
- To ListTopicViewsAsync(), a session needs the READ_TOPIC_VIEWS global permission.
- To CreateTopicViewAsync(String, String), or RemoveTopicViewAsync(String) a topic view, a session needs the MODIFY_TOPIC_VIEWS global permission and SELECT_TOPIC permission for the path prefix of the source topic selector.
- Each topic view records the principal and security roles of the session that created it as the topic view security context. When a topic view is evaluated, this security context is used to constrain the creation of reference topics. A reference topic will only be created if the security context has READ_TOPIC permission for the source topic path, and MODIFY_TOPIC permission for the reference topic path. The topic view security context is copied from the creating session at the time the topic view is created or replaced, and is persisted with the topic view. The topic view security context is not updated if the roles associated with the session are changed.
This feature may be obtained from a ISession as follows:
var topicViews = session.topicViews();
This feature is also extended by the ITopics feature. This means is it possible to use the methods described here through the ITopics feature.
Methods
CreateTopicViewAsync(String, String)
Create a new named topic view.
Declaration
Task<ITopicView> CreateTopicViewAsync(string name, string specification)
Parameters
Type | Name | Description |
---|---|---|
String | name | The name of the view. |
String | specification | The specification of the topic view. |
Returns
Type | Description |
---|---|
Task<ITopicView> | The |
Remarks
If a view with the same name already exists the new view will update the existing view.
If the operation completes successfully, the Task
result will be a
ITopicView instance.
Exceptions
Type | Condition |
---|---|
InvalidTopicViewException | The supplied specification is invalid. Thrown by the returned |
SessionSecurityException | The calling session does not have MODIFY_TOPIC_VIEWS permission or
appropriate path prefix permissions. Thrown by the returned |
SessionClosedException | The calling session is closed. Thrown by the returned |
ClusterRepartitionException | The cluster was repartitioning. Thrown by the returned |
See Also
CreateTopicViewAsync(String, String, CancellationToken)
Create a new named topic view.
Declaration
Task<ITopicView> CreateTopicViewAsync(string name, string specification, CancellationToken cancellationToken)
Parameters
Type | Name | Description |
---|---|---|
String | name | The name of the view. |
String | specification | The specification of the topic view. |
CancellationToken | cancellationToken | The cancellation token used to cancel the current operation. |
Returns
Type | Description |
---|---|
Task<ITopicView> | The |
Remarks
If a view with the same name already exists the new view will update the existing view.
If the operation completes successfully, the Task
result will be a
ITopicView instance.
Exceptions
Type | Condition |
---|---|
InvalidTopicViewException | The supplied specification is invalid. Thrown by the returned |
SessionSecurityException | The calling session does not have MODIFY_TOPIC_VIEWS permission or
appropriate path prefix permissions. Thrown by the returned |
SessionClosedException | The calling session is closed. Thrown by the returned |
ClusterRepartitionException | The cluster was repartitioning. Thrown by the returned |
ListTopicViewsAsync()
Declaration
Task<IReadOnlyCollection<ITopicView>> ListTopicViewsAsync()
Returns
Type | Description |
---|---|
Task<IReadOnlyCollection<ITopicView>> |
ListTopicViewsAsync(CancellationToken)
Declaration
Task<IReadOnlyCollection<ITopicView>> ListTopicViewsAsync(CancellationToken cancellationToken)
Parameters
Type | Name | Description |
---|---|---|
CancellationToken | cancellationToken |
Returns
Type | Description |
---|---|
Task<IReadOnlyCollection<ITopicView>> |
RemoveTopicViewAsync(String)
Remove a named topic view if it exists.
Declaration
Task<object> RemoveTopicViewAsync(string name)
Parameters
Type | Name | Description |
---|---|---|
String | name | The name of the view. |
Returns
Type | Description |
---|---|
Task<Object> | The |
Remarks
If the named view does not exist the Task
will complete successfully.
If the task completes successfully, the Task
result will be null
.
Exceptions
Type | Condition |
---|---|
SessionSecurityException | The calling session does not have MODIFY_TOPIC_VIEWS permission.
Thrown by the returned |
SessionClosedException | The calling session is closed. Thrown by the returned |
ClusterRepartitionException | The cluster was repartitioning. Thrown by the returned |
See Also
RemoveTopicViewAsync(String, CancellationToken)
Remove a named topic view if it exists.
Declaration
Task<object> RemoveTopicViewAsync(string name, CancellationToken cancellationToken)
Parameters
Type | Name | Description |
---|---|---|
String | name | The name of the view. |
CancellationToken | cancellationToken | The cancellation token used to cancel the current operation. |
Returns
Type | Description |
---|---|
Task<Object> | The |
Remarks
If the named view does not exist the Task
will complete successfully.
If the task completes successfully, the Task
result will be null
.
Exceptions
Type | Condition |
---|---|
SessionSecurityException | The calling session does not have MODIFY_TOPIC_VIEWS permission.
Thrown by the returned |
SessionClosedException | The calling session is closed. Thrown by the returned |
ClusterRepartitionException | The cluster was repartitioning. Thrown by the returned |