#Kafka Notifications
NETCONF and gNMI devices produce notifications, which UniConfig can collect to create its own UniConfig notifications about specific events. Notifications from both NETCONF and gNMI devices and UniConfig are published using Kafka.
The following notification types are available:
- NETCONF notifications
- gNMI notifications
- Notifications about transactions
- Audit logs (RESTCONF notifications)
- Data change events
- Connection notifications
Each notification type is stored in its own topic in Kafka. Additionally, all notifications are stored in one table in the database.
#Kafka
Apache Kafka is a publish–subscribe-based, durable messaging system that sends messages between processes, applications and servers. Within Kafka, you can define topics (categories) and applications can add, process and reprocess records.
In our particular case, UniConfig publishes notifications. Each type of notification is stored in a separate topic and can therefore be subscribed to independently. The names of topics and connection data are configurable in the application.properties file.
#NETCONF notifications
RFC 5277 defines a mechanism where a NETCONF client indicates an interest in receiving event notifications from a NETCONF server by subscribing to event notifications. The NETCONF server sends a reply about whether the subscription request was successful and, if so, starts sending event notifications to the NETCONF client as events occur within the system. Event notifications are sent until either the NETCONF session or the subscription is terminated.
NETCONF notifications are categorized as so-called streams. The subscriber can choose which streams to receive. The default stream is NETCONF
.
#gNMI notifications
The gNMI specification defines a mechanism where the gNMI client indicates an interest in receiving updates about the state of data instances via a subscribe RPC. If the subscription is successfully created, the gNMI server replies with the state of data instances according to specified paths.
The session remains open until it UniConfig closes it (releasing the subscription) or an error occurs on the device side. However, UniConfig will try to recreate the session.
The following fields are mandatory for the install-node
request:
stream-name
paths
#Notifications about transactions
This type of notification is generated after each commit in UniConfig.
It contains the following:
- transaction id
- calculate diff result
- commit result
#Audit logs (RESTCONF notifications)
This type of notification is generated after each RESTCONF operation.
It contains the following:
- transaction id
- comment
- label
- request data
- uri
- http method
- source address
- source port
- query parameters
- user id
- body
- response data
- status code
- query parameters
- body
The response body can be included or excluded from notifications with the includeResponseBody
parameter in the application.properties file. Similarly, the calculation difference result is included if the parameter includeCalculateDiffResult
parameter is set to true
in application.properties.
Below are three examples of notifications with the response body and the calculation difference result.
Example 1 - Created data
Example 2 - Deleted data
Example 3 - Updated data
#Shell notifications
This type of notification is generated after each shell operation. It contains the following:
- transaction id
- request data
- source address
- source port
- prompt
- executed command
- response data
- output
#Data change events
A subscription step is required before data change events are generated and published into Kafka.
With the subscription, a user can specify which subtrees are observed for data changes. Afterwards, data change events are generated by UniConfig instances when a transaction is committed and the committed changes contain subscribed subtrees.
A sample data change event captured by Kafka console consumer:
For data change events, streamName
is always DCE
and the identifier for the YANG notification is data-change-event
.
The body contains the following:
subscription-id
- Identifier for the subscription that triggers the generation of a data change event. The subscription identifier makes it easier to associate subscriptions and received data change events compared to using a combination of multiple fields such as node identifier, topology identifier and subtree path.transaction-id
- Identifier for the committed transaction that triggered the data change event after commit or checked-commit UniConfig operations.edit
- List of captured modifications done in the committed transaction.
Fields under edit
:
subtree-path
- Relative path to the data-tree element where the data change occurred. The path is relative to the subtree path specified during subscription.data-before
- JSON representation of subtree data before changes were made. If this field is not specified,data-after
represents created data.data-after
- JSON representation of subtree data including the changes. If this field is not specified,data-before
represents removed data.operation
- Operation type for the data change event.node-id
- Node identifier for the data change event.topology-id
- Topology identifier for the node. Eitheruniconfig
orunistore
.
#Connection notifications
Connection notification are generated whenever the status of a node changes. For connection notifications, streamName
is always CONNECTION
and the identifier for the YANG notification is connection-notification
.
Contains the following:
- topology id
- node id
- connection status
- connection message
Supported topologies are cli
, netconf
and gnmi
.
Sample connection notifications captured by Kafka console consumer:
CLI disconnect notification:
NETCONF connect notification:
gNMI connect notification:
#Database entities
The following three tables in the database are related to notifications:
- notification table
- settings table
- subscription table
The notification table is where notifications are stored. It contains the following columns:
- stream name - Name of the notification stream
- node id - Identifier for the NETCONF/gNMI device or, for other types of notifications, the UniConfig instance
- identifier - Name of the YANG notification for NETCONF or path to the received config top node for gNMI
- body - Full notification body in JSON format
- event time - Time when the notification was generated
Example - Request for reading notifications using RESTCONF:
The settings table contains two columns: identifier
and config
. Records with the kafka
identifier contain configurations for Kafka that can be modified at runtime.
Example - Request for reading Kafka settings using RESTCONF:
The subscription table is used to track NETCONF and gNMI notification subscriptions. It contains the following columns:
- node id - Identifier for the NETCONF/gNMI node where notifications are collected
- UniConfig instance id - Identifier for the UniConfig instance that collects notifications from the NETCONF/gNMI device
- stream name - NETCONF/gNMI stream name
- creation time - Time when the subscription was created
- start time - Start time for collecting notifications
- end time - End time for collecting notifications
Example - Request for reading subscriptions using RESTCONF:
#NETCONF subscriptions
A subscription is required to receive NETCONF notifications from a NETCONF device.
Subscriptions are created with an installation request:
Subscriptions to notification streams are defined as a list with the name stream
. There is one record for each stream.
The only mandatory parameter is stream-name
. Other parameters are optional:
start-time
- Must be specified to enable replay and should start at the specified time.stop-time
- Used with the optional replay feature to indicate the newest notifications of interest. If no stop time is specified, notifications will continue until the subscription is terminated. Must be used with and set to be later thanstart-time
. Values in the future are valid.
If a new subscription to a stream is created, all existing subscriptions to the stream are terminated.
#gNMI subscriptions
A subscription is required to receive gNMI notifications from a gNMI device.
Subscriptions are created with an installation request:
Subscriptions to notification streams are defined as a list with the name stream
. There is one record for each stream.
There are two required parameters, stream-name
and paths
. Other parameters are optional:
start-time
- Start time for telemetry streaming.stop-time
- Telemetry streaming stops if the timestamp of the notification is later than this time. If no stop time is specified, notifications will continue until the subscription is terminated. Must be used with and set to be later thanstart-time
. Values in the future are valid.
#Monitoring system - processing NETCONF/gNMI subscriptions
In UniConfig, subscriptions to NETCONF and gNMI notifications are processed in an infinite loop within the monitoring system.
An iteration of the monitoring system loop consists of following steps:
- Check global setting for NETCONF/gNMI notifications.
- If turned off, release all NETCONF/gNMI subscriptions and end current iteration.
- Release cancelled subscriptions.
- Query free subscriptions from DB, and for each one:
- Create a notification session (create mountpoint and register listeners).
- Lock the subscription (set UniConfig instance).
There is a hard limit on the number of sessions that a single UniConfig node can handle. If the limit is reached, the UniConfig node refuses any additional subscriptions.
The loop interval, hard subscription limit and maximum number of subscriptions processed per interval can be set in the application.properties file.
#Dedicated NETCONF session for subscription
A NETCONF device may have the interleave capability that indicates support for interleaving other NETCONF operations within a notification subscription. This means that the NETCONF server can receive, process and respond to NETCONF requests on a session with an active notification subscription.
As not all devices include support for this capability, the common approach for devices with and without interleave capability is to track notifications with a separate NETCONF session. To support this functionality, UniConfig creates a separate NETCONF session with a separate mountpoint for every subscription. These mountpoints and sessions are automatically terminated when the corresponding subscription is closed.
#Subscriptions to data change events
#Create a new subscription
Subscriptions to data change events are created using the create-data-change-subscription RPC. After a subscription is created, UniConfig listens to data change events on selected nodes and subtrees and distributes the corresponding messages to a dedicated Kafka topic.
RPC input contains the following:
node-id
- Identifier for the node from which data change events are generated. If not specified, a global subscription is created and data change events are generated for all nodes under the topology. This field is optional.topology-id
- Identifier for the topology where the specified node is placed.subtree-path
- Path to the subtree from which the user would like to receive data change events. The default value is/
, which captures data change events from the entire node configuration.data-change-scope
- Data-tree scope that specifies how granular data change events should be captured and propagated to Kafka. There are three options:SUBTREE
: Represents a change of the node or any of its child nodes, direct and nested. This scope is a superset ofONE
andBASE
. This is the default value.ONE
: Represent a change (an addition, replacement or deletion) of the node on the subtree-path or one of its direct child elements.BASE
: Represents only a direct change of the node on the subtree-path, such as replacement of a node, addition or deletion.
RPC output contains only the generated subscription identifier in UUID format. This identifier represents a token that can be used for the following:
- Display information about a created subscription using the RPC
- Delete an existing subscription
- Sort received Kafka messages
Example - Create a subscription to the device1
node in the uniconfig
topology, and to the whole /interfaces
configuration subtree:
Example - Create a duplicate subscription to the device1
node in the uniconfig
topology, and to the whole /interfaces
configuration subtree:
Example - Create a subscription to the uniconfig
topology and to the whole /interfaces
configuration subtree:
#Remove a subscription
Existing subscriptions can be removed using the delete-data-change-subscription RPC and the provided subscription-id
. After a subscription is removed, UniConfig stops generating new data change events related to the subscribed path.
RPC input contains only the subscription-id
, which is a unique identifier for the subscription to data change events.
RPC output does not contain a body. The RPC returns a 404 error if no subscription exists for the provided identifier.
Example - Remove a subscription:
- Successful example:
- Failed example:
#Show information about a subscription
The show-subscription-data RPC is used to display information about a created subscription.
RPC input contains an identifier for the target subscription.
RPC output for existing subscriptions contains the following:
topology-id
node-id
subtree-path
data-change-scope
These are the same fields that can be specified as input for the create-data-change-subscription RPC.
If no subscription exists with the specified ID, the RPC returns a 404 status code with a standard RESTCONF error container.
Successful example:
Failed example:
It is also possible to fetch all created subscriptions under a specific node or topology by sending a GET request to the data-change-subscriptions
list under the node
list item (operational data).
Example - Two subscriptions under the device1
node
#Configuration
Configurations for notifications are in the application.properties file, under the notifications
property.
The entire configuration looks like this:
All notifications, as well as the monitoring system, can be enabled or disabled using the enabled
flag.
Properties related to the monitoring system:
subscriptions-monitoring-interval
- How often the monitoring system loop is run and how often it attempts to acquire free subscriptions (in seconds). The default value is 5.max-subscriptions-per-interval
- The maximum number of free subscriptions that can be acquired in a single iteration of the monitoring system loop. If the number of free subscriptions is smaller than this value, all free subscriptions are processed. If the number of free subscriptions is larger than this value, only the specified number of subscriptions are acquired. The rest can be acquired during the next iterations of the monitoring system loop or by other UniConfing instances in the cluster. The default value is 10.max-netconf-subscriptions-hard-limit
- Maximum number of subscriptions that a single UniConfig node can handle.
Properties related to the monitoring system in clustered environments:
rebalance-on-UC-node-going-down-grace-period
- Grace period for a UniConfig node going down (in seconds). Other nodes will not restart subscriptions until the grace period has passed after a dead Uniconfig node was last seen. The default value is 120.optimal-subscriptions-approaching-margin
- Lower margin to calculate optimal range start. The default value is 0.05.optimal-subscriptions-reached-margin
- Upper margin to calculate optimal range end. The default value is 0.10.
Properties related to message timeout to Kafka:
blocking-timeout
- How long thesend()
method and the creation of a connection for reading metadata methods will block (in milliseconds).request-timeout
- How long the producer waits for acknowledgement of a request (in milliseconds). If no acknowledgement is received before the timeout period has passed, the producer resends the request or, if retries are exhausted, fails the request.delivery-timeout
- Upper bound on the time to report success or failure after a call tosend()
returns (in milliseconds). Sets a limit on the total time that a record will be delayed prior to sending, the time to wait for acknowledgement from the broker (if expected) and the time allowed for retriable send failures.
Properties related to the thread pool executor required to send messages to Kafka:
max-thread-pool-size
- Maximum thread pool size in the executor.queue-capacity
- Maximum capacity for the work queue in the executor.
Properties used to limit the number of records in the notifications table in the database:
max-count
- Maximum number of records in the notifications table. If the number of records exceeds this value, the oldest record in the table is deleted. The default value is 10,000.max-age
- Maximum age of a record in the notifications table (in hours). Records older than this value are deleted. The default value is 100.These properties are under
notification-db-treshold
. Both are implemented using database triggers. Triggers are running on inserts to the notifications table.
Audit log settings are under the audit-logs
property. Currently there is only one flag, include-response-body
, which is used to enable or disable logging the body of RESTCONF responses.
All settings related to Kafka are grouped under kafka
property. For authentication, there are the username
and password
properties. For the Kafka connection, there is the kafka-servers
property which contains a list of Kafka servers as a combination of broker-host
and broker-listening-port
. The broker host can be either an IP address or hostname.
Enable or disable each type of notification independently of others by using the following flags:
netconf-notifications-enabled
audit-logs-enabled
transaction-notifications-enabled
data-change-events-enabled
Configure the names of all topics for every notification type by using the following flags:
transactions-topic-name
- Topic name for transactions about notificationsnetconf-notifications-topic-name
- Topic name for NETCONF notificationsaudit-logs-topic-name
- Topic name for audit logsdata-change-events-topic-name
- Topic name for data change events
You can also to set up embedded Kafka using these setting grouped under the embeddedKafka
property:
enabled
- Enable or disable embedded Kafkainstall-dir
- Where Kafka files should be placedarchive-url
- Where to download Kafka fromdata-dir
- Kafka data directoryclean-data-before-start
- Whether or not to clear Kafka config before start
Kafka settings are also stored in the database. This way they can be changed at runtime using RESTCONF or UniConfig shell. Kafka setting are stored in the settings table.
#Kafka client - Example
To read notifications from Kafka, you can use the command line consumer.
Run the following command in the Kafka installation directory:
It is important to properly set up the hostname, port and topic name.
Output after a NETCONF notification is created: