This repo provides a library that shows how to use a subscribe request through gRPC Network Management Interface (gNMI) in order to retrieve PBR counter statistics with Cisco XR models. This project will expand to other data in future releases. Support for C++ is currently provided. Potential for other language support in future releases.
These are all provided/handled for ease of use:
User can find the specification for gNMI here:
https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-specification.md
User can find information regarding open-config here:
https://github.com/openconfig/public/tree/master
User can find the protos used here (Updated protos on April 22 2024): https://github.com/openconfig/gnmi/tree/master/proto The commands used to get the protos were: git clone <> followed by: git checkout SHA:
git clone https://github.com/openconfig/gnmi.git
git checkout 5588964b559c9afee319909dd022b6706fe4a162
User might need to add more protos in the future as dependencies for these proto files can change.
The gnmi.proto file has one change made on it:
import "github.com/openconfig/gnmi/proto/gnmi_ext/gnmi_ext.proto"; -> import "gnmi_ext.proto";
[!NOTE] We use docker containers, which handles the installation of the required packages and libraries. If the user wants to run this in their own environment, then please refer to the Dockerfile for the necessary installation packages.
-
Download last release
curl -LO https://github.com/cisco-open/gnmi-client-examples/<latest_release>
-
Include
mgbl_api
into your project.
-
Clone the repo.
git clone https://github.com/cisco-open/gnmi-client-examples/releases/tag/<latest_release>
-
Build Docker environment.
make build
-
To go into docker environment.
make sdk-bash
-
To build the library. The first build could take some time building the dependencies.\
By default Cmake will not build the tests To tell Cmake to build extra targets, do
cmake -DENABLE_UNIT_TESTS=ON -DENABLE_FUNC_TESTS=ON -DENABLE_SPHINX_DOC=ON ..
mkdir build && cd build
cmake ..
make
-
To install the lib
make install
-
To build the examples.
make examples
-
To run unit tests.
make unit_tests
-
To create the documentation.
build/subprojects/Build/documentation/sphinx/index.html
or in your local directory/usr/local/docs/sphinx/
make documentation
[!NOTE] It is highly recommened to view the documentation to understand how to use this library. Below is a brief overview.
This library uses gRPC's implementation of a Subscribe RPC. gRPC supports four types of RPC, but this library focuses on:
- Bidirectional Streaming RPC: Both the client and server can send and receive a stream of messages.
To understand how Subscribe RPCs work, it's important to know about Protocol Buffers. This is a language-agnostic, binary serialization format by Google, used to define data structures and services for gRPC. These are described in .proto
files.
In gRPC, services and their methods are defined in these .proto
files. For this library, the key focus is bidirectional streaming—where multiple requests and responses are exchanged as a stream over a single connection.
The .proto
files and their generated counterparts can be found here. The library uses RPCs and messages defined by gNMI. More details on the proto files are available in the Prerequisites section.
gRPC abstracts communication channels and streams into a unified concept, allowing you to define a service and its methods, specifying the parameters and return types.
Here’s a general workflow for subscription-based streaming with gRPC:
-
Create a
grpc::Channel
: This represents the connection to the server. -
Create a Stub: The stub is a client generated from the proto definitions. It uses the
grpc::Channel
to perform RPCs. -
Create a
grpc::ClientContext
: This allows you to attach metadata and configure settings for the RPC call. Its lifetime should match the stub's. -
Use
ClientReaderWriter
for Streaming: For bidirectional streaming, gRPC provides theClientReaderWriter
API. This API allows you to send requests and receive responses asynchronously via the stub. -
Send Requests and Wait for Responses: Once all requests are sent, signal the server that you are finished. The server will respond and, when complete, signal the client to stop listening for further responses. The process ends with receiving a
grpc::StatusCode
.
[!NOTE] Example usage can be found in the examples directory.
-
Initialize a
gnmi_client_connection
Object: This class manages the gRPC connection setup using thechannel_arguments
struct. It internally constructs thegrpc::Channel
. Typically, gRPC establishes the connection when the RPC is made, but the library provides await_for_grpc_server_connection
method to establish the connection prior to making an RPC call. -
Create a
gnmi_stream_imp
Object: Pass thegrpc::Channel
from the previous step into this object. The library handles the stub creation and streaming logic (ClientReaderWriter
) for you, abstracting most of the gRPC-specific details.
The following functions allow you to collect PBR (Policy-Based Routing) stats. The statistics provided are:
byte-count
packet-count
collection_timestamp_seconds
collection_timestamp_nanoseconds
path_grp_name
policy_action_type
std::pair<error_code, grpc::Status> GnmiClient::rpc_register_stats_once(
const client_context_args& context_args, rpc_args& rpc_args)
This is a blocking call that subscribes to PBR stats in "ONCE" mode. It retrieves all responses, parses them, and populates the counter structure for each pbr_key
. Each pbr_key
is a combination of key_policy
and key_rule
. After all responses are received or an rpc failure occurs, it returns a pair containing an error_code
and a grpc::Status
. Can be called multiple times one after another.
- Parameters:
context_args
: Configuration settings for the stream.rpc_args
: Parameters for the subscription.
Using "*"
for key_policy
and key_rule
will retrieve stats for all policy-rule combinations.
/**
* @brief Makes a stream request to the server.
* @param context_args Configuration for the client context.
* @param rpc_args Configuration for the RPC call.
* @return Error code indicating success or failure.
*/
error_code GnmiClient::rpc_register_stats_stream(const client_context_args& context_args,
rpc_args& rpc_args)
This is a non-blocking call that subscribes in "STREAM" mode. It sends the request and creates a receive thread that continuously waits for responses until the user cancels the RPC or an error occurs.
- Parameters:
context_args
: Configuration for the stream. Needs to exist for the lifetime of the rpc.rpc_args
: Parameters for the subscription.
For each response received, the user-defined _rpc_success_handler
will be executed in the receive thread, receiving a GnmiCounters
reference as an argument. This handler must process responses for each key_policy
and key_rule
combination, similar to the rpc_register_stats_once
function.
If the RPC fails, the user-defined _rpc_failed_handler
will be called in the receive thread, passing a grpc::Status
to handle the failure as needed.
Note: If multiple requests are sent, the same receive thread will handle all responses. After calling this function, always call stream_pbr_close
to cancel the RPC and join the thread. If the receive thread exists when sending multiple requests, it will keep using the original context_args. If the user wants to use different context_args, either create a new instance of the GnmiClient
and do the request there, or call stream_pbr_close
and then use this register function again.
error_code rpc_stream_close();
This is a blocking call that tries to cancel the RPC and waits to join the receive thread. Always call this after rpc_register_stats_stream
.
For more information please visit the official documentation and the given examples.
See the open issues for a list of proposed features (and known issues).
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions Users make are greatly appreciated. For detailed contributing guidelines, please see CONTRIBUTING.md
Distributed under the Apache License, Version 2.0
License. See LICENSE for more information.
Project Link: https://github.com/cisco-open/gnmi-client-examples
This template was adapted from https://github.com/othneildrew/Best-README-Template.