gRPC Network Management Interface (gNMI)
Contributors:
Paul Borman, Marcus Hines, Carl Lebsack, Chris Morrow, Anees Shaikh, Rob Shakir, Wen Bo Li, Darren Loher
Date:
May 25, 2023
Version:
0.10.0
gNMI service compatibility:
0.10.x
Table of Contents
- gRPC Network Management Interface (gNMI)
- Table of Contents
- 1 Introduction
- 2 Common Message Types and Encodings
- 3 Service Definition
- 4 Appendix: Current Protobuf Message and Service Specification
- 5 Appendix: Current Outstanding Issues/Future Features
- 6 Copyright
- 7 Revision History
1 Introduction
This document defines a gRPC-based protocol for the
modification and retrieval of configuration from a target device, as well as the
control and generation of telemetry streams from a target device to a data
collection system. The intention is that a single gRPC service definition can
cover both configuration and telemetry - allowing a single implementation on the
target, as well as a single NMS element to interact with the device via
telemetry and configuration RPCs.
All messages within the gRPC service definition are defined as protocol
buffers (specifically proto3).
gRPC service definitions are expected to be described using the relevant
features of the protobuf IDL. The protobuf definition of
gNMI is
maintained in the openconfig/gnmi GitHub
repository.
The service defined within this document is assumed to carry payloads that
contain data instances of OpenConfig YANG schemas,
but can be used for any data with the following characteristics:
- structure can be represented by a tree structure where nodes can be uniquely
identified by a path consisting of node names, or node names coupled with
attributes; - values can be serialised into a scalar object.
Currently, values may be serialised to a scalar object through encoding as a
JSON string or a Protobuf type - although the definition of new serialisations
is possible.
Throughout this specification the following terminology is used:
- Telemetry - refers to streaming data relating to underlying
characteristics of the device - either operational state or configuration. - Configuration - elements within the data schema which are read/write and
can be manipulated by the client. - Target - the device within the protocol which acts as the owner of the
data that is being manipulated or reported on. Typically this will be a
network device. - Client - the device or system using the protocol described in this
document to query/modify data on the target, or act as a collector for
streamed data. Typically this will be a network management system.
2 Common Message Types and Encodings
2.1 Reusable Notification Message Format
When a target wishes to communicate data relating to the state of its internal
database to an interested client, it does so via means of a common
Notification
message. Notification
messages are reused in other
higher-layer messages for various purposes. The exact use of the Notification
message is described on a per-RPC basis.
The fields of the Notification message are as follows:
timestamp
- The time at which the data was collected by the device from
the underlying source, or the time that the target generated the
Notification message (in the case that the data does not reflect an
underlying data source). This value is always represented according to the
definition in 2.2.1.prefix
- a prefix which is applied to all path fields (encoded as per
2.2.2) included in theNotification
message. The paths
expressed within the message are formed by the concatenation ofprefix + path
. Theprefix
always precedes thepath
elements. Further semantics
of prefixes are described in 2.4.1.update
- a list of update messages that indicate changes in the underlying
data of the target. Both modification and creation of data is expressed
through the update message.- An
Update
message has three subfields:path
- a path encoded as per 2.2.2.val
- a value encoded as per 2.2.3.duplicates
- a counter value that indicates the number of
coalesced duplicates. If a client is unable to keep up with the
server, coalescion can occur on a per update (i.e., per path) basis
such that the server can discard previous values for a given update
and return only the latest. In this case the server SHOULD increment
a count associated with the update such that a client can detect
that transitions in the state of the path have occurred, but were
suppressed due to its inability to keep up.
- The set of paths that are specified within the list of updates MUST be
unique. In this context, the path is defined to be the fully resolved
path (including the prefix). In the case that there is a duplicate path
specified within an update, only the final update should be processed by
the receiving entity.
- An
delete
- a list of paths (encoded as per 2.2.2) that
indicate the deletion of data nodes on the target.
The creator of a Notification message MUST include the timestamp
field. All
other fields are optional.
2.2 Common Data Types
2.2.1 Timestamps
Timestamp values MUST be represented as the number of nanoseconds since the Unix
epoch (January 1st 1970 00:00:00 UTC). The value MUST be encoded as a signed
64-bit integer (int64
)1.
2.2.2 Paths
Paths are represented according to gNMI Path
Conventions,
which defines a structured format for path elements, and any associated key
values. Rather than utilising a single string to represent the path - with the
/
character separating each element of the path, the path is represented by an
ordered list of PathElem
messages, starting at the root node, and ending at
the most specific path element. Each PathElem
message contains the name of the
node within the data tree, along with any associated keys/attributes that may be
required for it. Keys are contained within a map<string, string>
where the key
of the map is the name of the key element, and the value is the key’s value
encoded as a string.
A path is represented by the Path
message with the following fields:
origin
- a field which MAY be used to assert the schema the path belongs to.
A detailed description of origin is provided in
2.7.elem
- an array ofPathElem
messages, each containing the name of the
element, and any associated keys.target
- the name of the target for which the path is a member. Only set in
prefix
for a path. Elaboration of this field is in
2.2.2.1.
Each Path
element should correspond to a node in the data tree. For example,
the path /a/b/c/d
is encoded as:
path: <
elem: <
name: "a"
>
elem: <
name: "b"
>
elem: <
name: "c"
>
elem: <
name: "d"
>
>
Where attributes are to be specified, these are encoded alongside the node name
within the path element, for example a node specified by /a/e[key=k1]/f/g
would have the path encoded as:
path: <
elem: <
name: "a"
>
elem: <
name: "e"
key: <
key: "key"
value: "k1"
>
>
elem: <
name: "f"
>
elem: <
name: "g"
>
>
The root node (/
) is encoded as a zero-length array (slice) of PathElem
messages within the elem
field.
path: <
>
Paths (defined to be the concatenation of the prefix
and path
within the
message) specified within a message MUST be absolute - no messages with relative
paths should be generated.
2.2.2.1 Path Target
The target
field within a path is name for the target. This field MUST only
ever be present on prefix
paths in the corresponding request and response
messages. This field is optional for clients. When set in the prefix
in a
request, GetRequest
, SetRequest
or SubscribeRequest
, the field MUST be
reflected in the prefix
of the corresponding GetResponse
, SetResponse
or
SubscribeResponse
by a server. This field is used to allow a name to be
associated with all the data for a given stream if requested by a client. If a
client does not set this field in the prefix
of a request, it MUST NOT be set
in the prefix
of the corresponding response messages. The value for target
is tied to the context of a client RPC and not persisted or shared among
multiple clients.
2.2.3 Node Values
The value of a data node (or subtree) is encoded in a TypedValue
message as a
oneof
field to allow selection of the data type by setting exactly one of the member
fields. The possible data types include:
- scalar types
- structured data types (e.g., to encode objects or subtrees)
Several native scalar protobuf types are included in the TypedValue
message:
string
in thestring_val
field - defined to carry all string values
(including enumerated values represented as a string)int64
in theint_val
field (storing all signed integer types - i.e.,
int8
,int16
,int32
,int64
).uint64
in theuint_val
field (used to store all unsigned integer types -
i.e.,uint8
,uint16
,uint32
,uint64
).bool
in thebool_val
field, used to store boolean values.bytes
(see 2.3.2)float
in thedouble_val
field, used to store floating-point values (i.e.,
float32
,float64
).- Note: All values defined using the YANG
decimal64
datatype should also be
encoded asdouble_val
when PROTO encoding is requested. Direct support of
Decimal64 has been deprecated.
Additional defined data types include:
ScalarArray
in theleaflist_val
field – a message encoding a mixed-type
scalar array; contains single repeated field:element
– aTypedValue
element within the array. The type of each
element MUST be a scalar type (i.e., one of the scalar types).
The remaining fields in the TypedValue
message define structured data types.
Section 2.3 describes these further.
2.3 Structured data types
When structured data is sent by the client or the target in an Update
message,
it MUST be serialized according to one of the supported encodings listed in the
Encoding
enumeration. The table below lists the supported encodings and their
corresponding TypedValue
fields, followed by further details on each encoding
type. It should be noted that the target never utilises the Encoding
enumeration to declare to the client the type of encoding utilised, hence the
client must infer the encoding from the populated TypedValue
field.
Name | Description | TypedValue field |
Encoding Value |
---|---|---|---|
JSON | A JSON encoded string as per 2.3.1. | json_val |
0 |
Bytes | An arbitrary sequence of bytes as per 2.3.2. | bytes_val |
1 |
Proto | A Protobuf encoded message using scalar values as per Section 2.3.3. | string_val , int_val , uint_val , bool_val , bytes_val , float_val , leaflist_val |
2 |
ASCII | An ASCII encoded string representing text formatted according to a target-defined convention (described in Section 2.3.4). | ascii_val |
3 |
JSON_IETF | A JSON encoded string as per 2.3.1 using JSON encoding compatible with RFC 7951. | json_ietf_val |
4 |
2.3.1 JSON and JSON_IETF
The JSON
type indicates that the value is encoded as a JSON string. This
format utilises the specification in
RFC7159. Additional types (e.g.,
JSON_IETF
) are utilised to indicate specific additional characteristics of the
encoding of the JSON data (particularly where they relate to serialisation of
YANG-modeled data).
For any JSON encoding:
- In the case that the data item at the specified path is a leaf node (i.e.,
has no children, and an associated value) the value of that leaf is encoded
directly - i.e., the “bare” value is specified (i.e., a JSON object is not
required, and a bare JSON value is included). - Where the data item referred to has child nodes, the
val
field contains a
serialised JSON entity (object or array) corresponding to the referenced
item.
Using the following example data tree:
root +
|
+-- a +
|
+-- b[name=b1] +
|
+-- c +
|
+-- d (string)
+-- e (uint32)
The following serialisations would be used (note that the examples below follow
the conventions for textproto, and Go-style backticks are used for string
literals that would otherwise require escaping):
For /a/b[name=b1]/c/d
:
update: <
path: <
elem: <
name: "a"
>
elem: <
name: "b"
key: <
key: "name"
value: "b1"
>
>
elem: <
name: "c"
>
elem: <
name: "d"
>
>
val: <
json_val: "AStringValue"
>
>
For /a/b[name=b1]/c/e
:
update: <
path: <
elem: <
name: "a"
>
elem: <
name: "b"
key: <
key: "name"
value: "b1"
>
>
elem: <
name: "c"
>
elem: <
name: "e"
>
>
val: <
json_val: 10042 // decoded byte array
>
>
For /a/b[name=b1]/c
:
update: <
path: <
elem: <
name: "a"
>
elem: <
name: "b"
key: <
key: "name"
value: "b1"
>
>
elem: <
name: "c"
>
>
val: <
json_val: `{ "d": "AStringValue", "e": 10042 }`
>
>
For /a
:
update: <
path: <
elem: <
name: "a'
>
>
val: <
json_ietf_val: `{ "b": [
{
"name": "b1",
"c": {
"d": "AStringValue",
"e": 10042
}
}
]
}`
>
>
Note that all JSON values MUST be valid JSON. That is to say, while a value or
object may be included in the message, the relevant quoting according to the
JSON specification in RFC7159 must be
used. This results in quoted string values, and unquoted number values.
JSON_IETF
encoded data MUST conform with the rules for JSON serialisation
described in RFC7951. Data specified with
a type of JSON MUST be valid JSON, but no additional constraints are placed upon
it. An implementation MUST NOT serialise data with mixed JSON
and JSON_IETF
encodings.
Both the client and target MUST support the JSON
encoding as a minimum.
2.3.2 Bytes
Data encoded using the BYTES
type (i.e., with the byte_val
field) contains a
byte sequence whose semantics is opaque to the protocol.
2.3.3 Protobuf
Data encoded using the PROTOBUF
type should use the TypedValue message using
primitive types as described in Section 2.2.3.
2.3.4 ASCII
The ASCII
type indicates that the data contains system-formatted ASCII encoded
text. For configuration data, for example, this may consist of semi-structured
CLI configuration data formatted according to the target platform. The gNMI
protocol does not define the format of the text – this must be established
out-of-band.
2.4 Use of Data Schema Paths
2.4.1 Path Prefixes
In a number of messages, a prefix can be specified to reduce the lengths of path
fields within the message. In this case, a prefix
field is specified within a
message - comprising of a valid path encoded according to Section
2.2.2. In the case that a prefix is specified, the absolute path
is comprised of the concatenation of the list of path elements representing the
prefix and the list of path elements in the path
field.
For example, again considering the data tree shown in Section
2.3.1 if a Notification
message updating values, a
prefix could be used to refer to the /a/b[name=b1]/c/d
and /a/b[name=b1]/c/e
data nodes:
notification: <
timestamp: (timestamp) // timestamp as int64
prefix: <
elem: <
name: "a"
>
elem: <
name: "b"
key: <
key: "name"
value: "b1"
>
>
elem: <
name: "c"
>
>
update: <
path: <
elem: <
name: "d"
>
>
value: <
val: <
json_val: "AStringValue"
>
>
>
update: <
path: <
elem: <
name: "e"
>
>
val: <
json_val: 10042 // converted to int representation
>
>
>
2.4.2 Interpretation of Paths Used in RPCs
When a client specifies a path within an RPC message which indicates a read, or
retrieval of data, the path MUST be interpreted such that it refers to the node
directly corresponding with the path and all its children. The path refers
to the direct node and all descendent branches which originate from the node,
recursively down to each leaf element. If specific nodes are expected to be
excluded then an RPC MAY provide means to filter nodes, such as
regular-expression based filtering, lists of excluded paths, or metadata-based
filtering (based on annotations of the data schema being manipulated, should
such annotations be available and understood by both client and target).
For example, consider the following data tree:
root +
|
+-- childA +
| |
| +-- leafA1
| +-- leafA2
| +-- childA3 --+
| |
| +-- leafA31
| +-- leafA32
|
+-- childB +
|
+-- leafB1
+-- leafB2
A path referring to “root” (which is represented by a path
consisting of an
empty set of elements) should result in the nodes childA
and childB
and all
of their children (leafA1, leafA2, leafB1, leafB2, childA3, leafA31
and
leafA32
) being considered by the relevant operation.
In the case that the RPC is modifying the state of data (i.e., a write
operation), such recursion is not required - rather the modification operation
should be considered to be targeted at the node within the schema that is
specified by the path, and the value should be deserialized such that it
modifies the content of any child nodes if required to do so.
2.5 Error handling
Errors MUST be represented by a canonical gRPC error code
(Java,
Go,
C++). The entity
generating the error MUST specify a free-text string which indicates the context
of the error, allowing the receiving entity to generate log entries that allow a
human operator to understand the exact error that occurred, and its context, and
MAY supply structured data encoded as protobuf.Any
. Each RPC defines the
meaning of the relevant canonical error codes within the context of the
operation it performs.
The canonical error code that is chosen MUST consider the expected behavior of
the client on receipt of the message. For example, error codes which indicate
that a client may subsequently retry SHOULD only be used where retrying the RPC
is expected to result in a different outcome.
Where the client or target wishes to indicate an error, it MUST use the Status
message in the RPC return trailers.
The Status
message consists of three fields:
code
- a 32-bit integer value corresponding to the canonical gRPC error
codemessage
- a human-readable string describing the error condition. This
string is not expected to be machine-parsable, but rather provide contextual
information which may be passed to upstream systems.details
- a repeated field ofprotobuf.Any
messages that carry error
details.
2.6 Schema Definition Models
The data tree supported by the target is expected to be defined by a set of
schemas. The definition and format of these models is out of scope of this
specification (YANG-modeled data is one example). In the case that such schema
definitions are used, the client should be able to determine the models that are
supported by the target, so that it can generate valid modifications to the data
tree, and interpret the data returned by Get
and Subscribe
RPC calls.
Additionally, the client may wish to restrict the set of models that are
utilised by the target so that it can validate the data returned to it against a
specific set of data models. This is particularly relevant where the target may
otherwise add new values to restricted value data elements (e.g., those
representing an enumerated type), or augment new data elements into the data
tree.
In order to allow the client to restrict the set of data models to be used when
interacting with the target, the client MAY discover the set of models that are
supported by the target using the Capabilities
RPC described in Section
3.2. For subsequent Get
and Subscribe
RPCs, the
client MAY specify the models to be used by the target. The set of models to
use is expressed as a ModelData
message, as specified in Section
2.6.1.
If the client specifies a set of models in a Get
or Subscribe
RPC, the
target MUST NOT utilize data tree elements that are defined in schema modules
outside the specified set. In addition, where there are data tree elements that
have restricted value sets (e.g., enumerated types), and the set is extended by
a module which is outside of the set, such values MUST NOT be used in data
instances that are sent to the client. Where there are other elements of the
schema that depend on the existence of such enumerated values, the target MUST
NOT include such values in data instances sent to the client.
2.6.1 The ModelData message
The ModelData
message describes a specific model that is supported by the
target and used by the client. The fields of the ModelData
message identify a
data model registered in a model catalog, as described in
[MODEL_CATALOG_DOC]
(the schema of the catalog itself - expressed in YANG - is described in
[MODEL_CATALOG_YANG]).
Each model specified by a ModelData
message may refer to a specific schema
module, a bundle of modules, or an augmentation or deviation, as described by
the catalog entry.
Each ModelData
message contains the following fields:
name
- name of the model expressed as a string.organization
- the organization publishing the model, expressed as a
string.version
- the supported (or requested) version of the model, expressed as
a string which represents the semantic version of the catalog entry.
The combination of name
, organization
, and version
uniquely identifies an entry in the model catalog.
2.7 gNMI Origin in Path
The origin
field in the Path
message identifies a schema that the path
belongs to. origin
is encoded as a string. The path specified within the
message is uniquely identified by the tuple of <origin, path>
.
The origin
field is valid in any context of a Path
message. Typically it is
used:
- In a
SetRequest
to indicate a particular schema is being used to modify
the target configuration. - In a
GetRequest
to retrieve the contents of a particular schema, or in
aGetResponse
to indicate that the payload contains data from a
particular<origin, path>
schema. - In a
SubscribeRequest
to subscribe to paths within a particular schema,
orSubscribeResponse
to indicate an update corresponds to a particular
<origin, path>
tuple.
If more than one origin
is to be used within any message, a path in the
prefix
MUST NOT be specified, since a prefix applies to all paths within the
message. In the case that a prefix
is specified, it MUST specify any required
origin
. A single request MUST NOT specify origin
in both prefix
and path
fields in any RPC payload messages.
2.7.1 Special Values of origin
Origin values are agreed out of band to the gNMI protocol. Currently, special
values are registered within this section of this document. Should additional
origins be defined, a registry will be defined.
Where the origin
field is unspecified, its value should default to
openconfig
. It is RECOMMENDED that the origin is explictly set.
Where the origin
field is set to a command line interface format, the path
should be ignored and the value specified within the Update
considered as CLI
input.
CLI configuration is defined as the command line interface text used for
configuration. In gNMI, this is encoded as ASCII text. The format of the ASCII
text is agreed to out of band from gNMI. The string used to identify the CLI
origin must be formatted as origin:<nos_cli>
. Example values might include:
xros_cli
, junos_cli
, srlinux_cli
or any string which indicates the NOS
name and the CLI designation.
2.7.2 Definition of origin
for YANG-modelled Data
The openconfig-extensions:origin
field MAY be utilised to determine the
origin within which a particular module is instantiated. The specification of
this extension is within
openconfig-extensions.yang.
It should be noted that origin
is distinct from namespace
. Whilst a YANG
namespace is defined at any depth within the schema tree, an origin
is
only used to disambiguate entire schema trees. That is to say, any element
that is not at the root inherits its origin
from its root entity, regardless
of the YANG schema modules that make up that root.
2.7.3 Partial Specifications of Origin in Set
If a Set
RPC specifies delete
, update
, or replace
fields which include
an origin
within their Path
messages, the corresponding change MUST be
constrained to the specified origin. Particularly:
replace
operations MUST only replace the contents of the specifiedorigin
at the specified path. Origins that are not specified within theSetRequest
MUST NOT have their contents replaced. In order for areplace
operation to
replace any contents of anorigin
it must be explicitly specified in the
SetRequest
.delete
operations MUST delete only the contents at the specified path within
the specifiedorigin
. To delete contents from multiple origins, a client
MUST specify multiple paths within thedelete
of theSetRequest
.
These rules apply where origins represent data that doesn’t overlap. in some
cases (e.g., CLI and OpenConfig) origins may reflect different ‘views’ on the
same data, and thus their interaction is more complex. See
union_replace
for more details, and behavioural specifications for such origins.
2.7.4 Transactionality of Sets with multiple Origins
Where a SetRequest
specifies more than one origin
- i.e., two or more
operations whose path include more than one origin - manipulations to all
affected trees MUST be considered as a single transaction. That is to say, only
if all transactions succeed should the SetResponse
indicate success. If any
of the transactions fail, the contents of all origins MUST be rolled back, and
an error status returned upon responding to the Set
RPC.
2.8 Extensions to gNMI
Each top-level RPC message (e.g., SubscribeRequest
and SubscribeResponse
for
the Subscribe
RPC) defines an extensions
field which can be used to carry
additional parameters for a gNMI RPC.
[GNMI-EXT]
defines the mechanisms to define such extensions. It must be noted that the base
operation of the RPCs as described in this specification MUST NOT be modified by
an extension.
3 Service Definition
A single gRPC service is defined - future revisions of this specification MAY
result in additional services being introduced, and hence an implementation MUST
NOT make assumptions that limit to a single service definition.
The service consists of the following RPCs:
Capabilities
- defined in Section 3.2 and used
by the client and target as an initial handshake to exchange capability
informationGet
- defined in Section
3.3, used to retrieve
snapshots of the data on the target by the client.Set
- defined in Section 3.4 and used by the client
to modify the state of the target.Subscribe
- defined in Section 3.5
and used to control subscriptions to data on the target by the client.
A target implementing the gNMI service SHOULD register against the gRPC server
reflection
service to
allow clients to determine that gNMI is available on the target.
3.1 Session Security, Authentication and RPC Authorization
The session between the client and server MUST be encrypted using TLS - and a
target or client MUST NOT fall back to unencrypted sessions. The target and
client SHOULD implement TLS >= 1.2.
New connections are mutually authenticated – each entity validates the X.509
certificate of the remote entity to ensure that the remote entity is both known,
and authorized to connect to the local system.
If the target is expected to authenticate an RPC operation, the client MUST
supply a username and password in the metadata of the RPC message (e.g.,
SubscribeRequest
, GetRequest
or SetRequest
). If the client supplies
username/password credentials, the target MUST authenticate the RPC per its
local authentication functionality.
Authorization is also performed per-RPC by the server, through validating
client-provided metadata. The client MAY include the appropriate AAA metadata,
which MUST contain a username, and MAY include a password in the context of each
RPC call it generates. If the client includes both username and password, the
target MUST authenticate and authorize the request. If the client only supplies
the username, the target MUST authorize the RPC request.
A more detailed discussion of the requirements for authentication and encryption
used for gNMI is in
[GNMI-AUTH].
3.2 Capability Discovery
A client MAY discover the capabilities of the target using the Capabilities
RPC. The CapabilityRequest
message is sent by the client to interrogate the
target. The target MUST reply with a CapabilityResponse
message that
includes its gNMI service version, the versioned data models it supports, and
the supported data encodings. This information is used in subsequent RPC
messages from the client to indicate the set of models that the client will use
(for Get
, Subscribe
as described in Section
2.6) , and the encoding to be used for the data.
When the client does not specify the models it is using, the target SHOULD use
all data schema modules that it supports when considering the data tree to be
addressed. If the client does not specify the encoding in an RPC message, it
MUST send JSON encoded values (the default encoding).
3.2.1 The CapabilityRequest message
The CapabilityRequest
message is sent by the client to request capability
information from the target. The CapabilityRequest
message carries a single
repeated extension
field, which is used as per the definition in Section
2.8.
3.2.2 The CapabilityResponse message
The CapabilityResponse
message has the following fields:
supported_models
- a set ofModelData
messages (as defined in Section
2.6.1) describing each of the models supported
by the targetsupported_encodings
- an enumeration field describing the data encodings
supported by the target, as described in Section
2.3.gNMI_version
- the semantic version of the gNMI service supported by the
target, specified as a string. The version should be interpreted as per
[OPENCONFIG-SEMVER].extension
- a repeated field to carry gNMI extensions, which is used as
per the definition in Section 2.8.
3.3 Retrieving Snapshots of State Information
In some cases, a client may require a snapshot of the state that exists on the
target. In such cases, a client desires some subtree of the data tree to be
serialized by the target and transmitted to it. It is expected that the values
that are retrieved (whether writeable by the client or not) are collected
immediately and provided to the client.
The Get
RPC provides an interface by which a client can request a set of paths
to be serialized and transmitted to it by the target. The client sends a
GetRequest
message to the target, specifying the data that is to be retrieved.
The fields of the GetRequest
message are described in Section
3.3.1.
Upon reception of a GetRequest
, the target serializes the requested paths, and
returns a GetResponse
message. The target MUST reflect the values of the
specified leaves at a particular collection time, which MAY be different for
each path specified within the GetRequest
message.
The target closes the Get
RPC following the transmission of the GetResponse
message.
3.3.1 The GetRequest Message
The GetRequest
message contains the following fields:
prefix
- a path (specified as per Section 2.2.2), and used
as described in Section 2.4.1. The prefix is applied
to all paths within theGetRequest
message.path
- a set of paths (expressed as per Section 2.2.2) for
which the client is requesting a data snapshot from the target. The path
specified MAY utilize wildcards. In the case that the path specified is not
valid, the target MUST return an RPC response indicating an error code of
InvalidArgument
and SHOULD provide information about the invalid path in
the error message or details.type
- the type of data that is requested from the target. The valid
values for type are described below.encoding
- the encoding that the target should utilise to serialise the
subtree of the data tree requested. The type MUST be one of the encodings
specified in Section 2.3. If the
Capabilities
RPC has been utilised, the client SHOULD use an encoding
advertised as supported by the target. If the encoding is not specified,
JSON MUST be used. If the target does not support the specified encoding,
the target MUST return an error ofUnimplemented
. The error message MUST
indicate that the specified encoding is unsupported.use_models
- a set ofModelData
messages (defined in Section
2.6.1) indicating the schema definition modules
that define the data elements that should be returned in response to the Get
RPC call. The semantics of theuse_models
field are defined in Section
2.6.extension
- a repeated field to carry gNMI extensions, used as per the
definition in Section 2.8.
Since the data tree stored by the target may consist of different types of data
(e.g., values that are operational in nature, such as protocol statistics) - the
client MAY specify that a subset of values in the tree are of interest. In order
for such filtering to be implemented, the data schema on the target MUST be
annotated in a manner which specifies the type of data for individual leaves, or
subtrees of the data tree.
The types of data currently defined are:
CONFIG
- specified to be data that the target considers to be read/write.
If the data schema is described in YANG, this corresponds to the “config
true” set of leaves on the target.STATE
- specified to be the read-only data on the target. If the data
schema is described in YANG,STATE
data is the “config false” set of
leaves on the target.OPERATIONAL
- specified to be the read-only data on the target that is
related to software processes operating on the device, or external
interactions of the device.
If the type
field is not specified, the target MUST return CONFIG, STATE and
OPERATIONAL data fields in the tree resulting from the client’s query.
3.3.2 The GetResponse Message
The GetResponse
message consists of:
notification
- a set ofNotification
messages, as defined in Section
2.1. The target MUST generate a
Notification
message for each path specified in the client’sGetRequest
,
and hence MUST NOT collapse data from multiple paths into a single
Notification
within the response. Thetimestamp
field of the
Notification
message MUST be set to the time at which the target’s
snapshot of the relevant path was taken.extension
- a repeated field used to carry gNMI extensions, as per the
description in Section 2.8.
3.3.3 Considerations for using Get
The Get
RPC is intended for clients to retrieve relatively small sets of data
as complete objects, for example a part of the configuration. Such requests are
not expected to put a significant resource burden on the target. Since the
target is expected to return the entire snapshot in the GetResponse
message,
Get
is not well-suited for retrieving very large data sets, such as the full
contents of the routing table, or the entire component inventory. For such
operations, the Subscribe
RPC is the recommended mechanism, e.g. using the
ONCE
mode as described in Section 3.5.
Another consideration for Get
is that the timestamp returned is associated
with entire set of data requested, although individual data items may have been
sampled by the target at different times. If the client requires higher
accuracy for individual data items, the Subscribe
RPC is recommended to
request a telemetry stream (see Section
3.5.2).
3.3.4 GetResponse Behavior Table
The following table clarifies the target behaviors for Get
for certain scenarios:
GetRequest Scenario | Target Behavior |
---|---|
Requested paths exist or a YANG default value is in use. | Value(s) are returned |
Requested paths are syntactically correct but one or more paths neither exist (yet) nor has a YANG default value in use. | Return NOT_FOUND |
Requested paths are syntactically correct but one or more paths is not implemented by the server. | Return UNIMPLEMENTED |
One or more requested paths is syntactically incorrect. | Return INVALID_ARGUMENT |
3.4 Modifying State
Modifications to the state of the target are made through the Set
RPC. A
client sends a SetRequest
message to the target indicating the modifications
it desires.
A target receiving a SetRequest
message processes the operations specified
within it - which are treated as a transaction (see Section
3.4.3). Where a SetRequest contains delete, replace, and
update fields, the server MUST process paths in the following order:
- deleted paths (within the
delete
field of theSetRequest
) - replaced paths (within the
replace
field) - updated paths (within the
update
field)
A SetRequest containing
union_replace
operations MUST NOT contain delete, replace and update operations.
The order of the fields MUST be treated as significant within a
single SetRequest
message. If a single path is specified multiple times for a
single operation (i.e., within update
or replace
), then the state of the
target MUST reflect the application of all of the operations in order, even if
they overwrite each other. A SetRequest
specifying an empty set of paths MUST
NOT be treated as an error by the target. For example, a SetRequest
message
carrying only extensions is valid.
In response to a SetRequest
, the target MUST respond with a SetResponse
message. For each operation specified in the SetRequest
message, an
UpdateResult
message MUST be included in the response field of the
SetResponse
. The order in which the operations are applied MUST be maintained
such that UpdateResult
messages can be correlated to the SetRequest
operations. In the case of a failure of an operation, the status of the
UpdateResult
message MUST be populated with error information as per the
specification in Section 3.4.7. In addition, the status
of the SetResponse
message MUST be populated with an error message indicating
the success or failure of the set of operations within the SetRequest
message
(again using the error handling behavior defined in Section
3.4.7).
3.4.1 The SetRequest Message
A SetRequest
message consists of the following fields:
prefix
- specified as per Section 2.4.1. The prefix
specified is applied to all paths defined within other fields of the
message.delete
- A set of paths, specified as per Section 2.2.2,
which are to be removed from the data tree. A specification of the behavior
of a delete is defined in Section 3.4.6.union_replace
- A set ofUpdate
messages specifying elements to union and
then replace the data tree. See the gNMI union_replace specification
for details.replace
- A set ofUpdate
messages indicating elements of the data tree
whose content is to be replaced.update
- A set ofUpdate
messages indicating elements of the data tree
whose content is to be updated.extension
- a repeated field used to carry gNMI extensions, as per the
description in Section 2.8.
The semantics of “updating” versus “replacing” content are defined in Section
3.4.4.
A re-usable Update
message is utilised to indicate changes to paths where a
new value is required. The Update
message contains two fields:
path
- a path encoded as per Section 2.2.2 indicating the
path of the element to be modified.value
- a value encoded as per Section 2.2.3
indicating the value applied to the specified node. The semantics of how the
node is updated is dependent upon the context of the update message, as
specified in Section 3.4.4.
3.4.2 The SetResponse Message
A SetResponse
consists of the following fields:
prefix
- specified as per Section 2.4.1. The prefix
specified is applied to all paths defined within other fields of the
message. The target MUST return an RPC response when the change is
successfully applied. In cases where an update was not successfully applied,
the contents of the status message used in the RPC response MUST be
specified as per Section 3.4.7.response
- containing a list of responses, one per operation specified
within theSetRequest
message. Each response consists of anUpdateResult
message with the following fields:timestamp
- a timestamp (encoded as per Section
2.2.1) at which the set request message was accepted
by the system.path
- the path (encoded as per Section 2.2.2) specified
within theSetRequest
. In the case that a common prefix was not used
within theSetRequest
, the target MAY specify aprefix
to reduce
repetition of path elements within multipleUpdateResult
messages in
therequest
field.op
- the operation corresponding to the path. This value MUST be one
ofDELETE
,REPLACE
, orUPDATE
.message
- a status message (as specified in Section
2.5). This field follows the same rules as the
status field returned with theSetResponse
message specified above.
extension
- a repeated field used to carry gNMI extensions, as per the
description in Section 2.8.
3.4.3 Transactions
All changes to the state of the target that are included in an individual
SetRequest
message are considered part of a transaction. That is, either all
modifications within the request are applied, or the target MUST rollback the
state changes to reflect its state before any changes were applied. The state of
the target MUST NOT appear to be changed until such time as all changes have
been accepted successfully. Hence, telemetry update messages MUST NOT reflect
a change in state until such time as the intended modifications have been
accepted.
As per the specification in Section 3.4, within an
individual transaction (SetRequest
) the order of operations is delete
,
union_replace
, replace
, update
.
As the scope of a “transaction” is a single SetRequest
message, a client
desiring a set of changes to be applied together MUST ensure that they are
encapsulated within a single SetRequest
message.
3.4.4 Modes of Update: Union replace, Replace and Update
Changes to read-write values on the target are applied based on the
union_replace
, replace
and update
fields of the SetRequest
message.
For these update operations, if the path specified does not exist,
the target MUST create the data tree element and populate it with the data in
the Update
message, provided the path is valid according to the data tree
schema. If invalid values are specified, the target MUST cease processing
updates within the SetRequest
method, return the data tree to the state prior
to any changes, and return a SetResponse
status indicating the error
encountered.
Where the path specified refers to a node which itself represents the collection
of objects (list, map, or array), a replace operation MUST remove all collection
entries that are not supplied in the value provided in the SetRequest
. An
update operation MUST be considered to add new entries to the collection if they
do not exist.
For union_replace
operations, the contents contents shall be merged (unioned)
and then applied as a replacement of the configuration. See the
gNMI union_replace specification.
For replace
operations:
- If a particular path-value is specified in the client-supplied data, it is
replaced with the client-specified value. - If a particular path-value is NOT specified in the client-supplied data and
the path does not have a specified default value in the corresponding schema,
it should be deleted. - If a path-value is NOT specified in the client-supplied data and the path does
have a default value, it takes on the schema-specified default value.
For example, consider the following tree, where a schema defines the boolean b
as having a default value of True and boolean c
as having no default value.
Both b
and c
have been previously set as False.
root +
|
+ a --+
| |
| +-- b
| |
| +-- c
|
|
+ d --+
+-- e
|
+-- f
A replace
operation is issued where e
and f
are set, and all other
elements are omitted. In this scenario, b
MUST be reverted to its default
setting of True and the configuration of c
MUST be deleted from the tree,
and returned to its original un-configured setting.
replace
MUST not be used as a way to delete configuration at the path
specified by being supplied with a null or invalid value. For example, it is
invalid to replace a keyed list element (e.g. /a/f[k=10]
) with an empty JSON
object {}
, which implicitly deletes the list’s keys and renders the list
element keyless. It is also invalid to replace a leaf value (e.g. the boolean
b
) with a nil
value instead of a boolean value. In both of the above cases,
the target MUST reject the operation by returning INVALID_ARGUMENT
.
For update
operations:
- Only the value of those data elements that are specified explicitly should be
treated as changed. - It is only possible to update or create new leaf elements, and not possible
to delete leaf elements using anupdate
operation.
For example, if an update
operation to the root element /
is done on the
following data tree, where f[k=20]
and f[k=30]
are the elements that are in
the SetRequest
, then list element f[k=10]
is untouched.
Before:
root +
|
+ a --+
|
+-- f[k=10] --+
| |
| +-- k = 10
| +-- v = hello
|
+-- f[k=20] --+
|
+-- k = 20
+-- v = world
After:
root +
|
+ a --+
|
+-- f[k=10] --+
| |
| +-- k = 10
| +-- v = hello
|
+-- f[k=20] --+
| |
| +-- k = 20
| +-- v = solar
|
+-- f[k=30] --+
|
+-- k = 30
+-- v = system
3.4.5 Modifying Paths Identified by Attributes
The path convention defined in Section 2.2.2 allows nodes in the
data tree to be identified by a unique set of node names (e.g.,/a/b/c/d
) or
paths that consist of node names coupled with attributes (e.g., /a/e[key=10]
).
In the case where where a node name plus attribute name is required to uniquely
identify an element (i.e., the path within the schema represents a list, map, or
array), the following considerations apply:
- In the case that multiple attribute values are required to uniquely address
an element - e.g.,/a/f[k1=10][k2=20]
- and a replace or update
operation’s path specifies a subset of the attributes (e.g.,/a/f[k1=10]
)
then this MUST be considered an error by the target system - and an status
code ofInvalidArgument (3)
specified. - In the case that key values are specified both as attributes of a node, and
as their own elements within the data tree, update or replace operations
that modify instances of the key in conflicting ways MUST be considered an
error. The target MUST return a status code ofInvalidArgument (3)
.
For example, consider a tree corresponding to the examples above, as illustrated
below.
root +
|
+ a --+
|
+-- f[k1=10][k2=20] --+
| |
| +-- k1 = 10
| +-- k2 = 20
|
+-- f[k1=10][k2=21] --+
|
+-- k1 = 10
+-- k2 = 21
In this case, nodes k1
and k2
are standalone nodes within the schema, but
also correspond to attribute values for the node “f
”. In this case, an update
or replace message specifying a path of /a/f[k1=10][k2=20]
setting the value
of k1
to 100 MUST be considered erroneous, and a status code of
InvalidArgument (3)
specified.
3.4.6 Deleting Configuration
Where a path is contained within the delete
field of the SetRequest
message,
it should be removed from the target’s data tree. In the case that the path
specified is to an element that has children, these children MUST be recursively
deleted. If a wildcard path is utilised, the wildcards MUST be expanded by the
target, and the corresponding elements of the data tree deleted. Such wildcards
MUST support paths specifying a subset of attributes required to identify
entries within a collection (list, array, or map) of the data schema.
In the case that a path specifies an element within the data tree that does not
exist, these deletes MUST be silently accepted.
3.4.7 Error Handling
When a client issues a SetRequest
, and the target is unable to apply the
specified changes, an error status MUST be reported to the client. The error is
specified in multiple places:
- The status returned with the
SetResponse
message indicates the completion
status of the entire transaction. - With a
UpdateResult
message, where the message field indicates the
completion status of the individual operation.
The RPC status supplied with the SetResponse
message MUST reflect the overall
result of the transaction.
In the case that any operation within the SetRequest
message fails, then (as
per Section 3.4.3), the target MUST NOT apply any of the
specified changes, and MUST consider the transaction as failed. The target
SHOULD set the status code of the SetResponse
message to Aborted (10)
, along
with an appropriate error message, and MUST set the message
field of the
UpdateResult
corresponding to the failed operation to an Error
message
indicating failure. In the case that the processed operation is not the only
operation within the SetRequest
the target MUST set the message
field of the
UpdateResult
messages for all other operations, setting the code field to
Aborted (10)
.
For the operation that the target is unable to process, the code indicated in
the status message returned within the RPC response MUST be set to a specific
error code indicating the reason for failure based on the following mappings to
canonical gRPC error codes:
- When the client has specified metadata requiring authentication (see Section
3.1), and the
authentication fails -Unauthenticated (16)
. - When the client does not have permission to modify the path specified by the
operation -PermissionDenied (7)
. - When the operation specifies a path that cannot be parsed by the target -
InvalidArgument (3)
. In this case, themessage
field of the returned
status specified SHOULD specify human-readable text indicating that the path
could not be parsed. - When the operation is an
update
,replace
orunion_replace
operation that
corresponds to a path that is not valid -NotFound (5)
. In this case the
message
field of the returned status message SHOULD specify human-readable
text indicating the path that was invalid. - When the operation is an
update
,replace
orunion_replace
operation that
includes an invalid value within theUpdate
message specified -
InvalidArgument (3)
. This error SHOULD be used in cases where the payload
specifies scalar values that do not correspond to the correct schema type. - When the client specifies a payload utilising an encoding that is not
supported by the target (e.g., JSON) -Unimplemented (12)
SHOULD be used to
indicate that the encoding is not supported.
3.5 Subscribing to Telemetry Updates
When a client wishes to receive updates relating to the state of data instances
on a target, it creates a subscription via the Subscribe
RPC. A subscription
consists of one or more paths, with a specified subscription mode. The mode of
each subscription determines the triggers for updates for data sent from the
target to the client.
All requests for new subscriptions are encapsulated within a SubscribeRequest
message - which itself has a mode which describes the longevity of the
subscription. A client may create a subscription which has a dedicated stream to
return one-off data (ONCE
); a subscription that utilizes a stream to
periodically request a set of data (POLL
); or a long-lived subscription that
streams data according to the triggers specified within the individual
subscription’s mode (STREAM
).
The target generates messages according to the type of subscription that has
been created, at the frequency requested by the client. The methods to create
subscriptions are described in Section 3.5.1.
Subscriptions are created for a set of paths - which cannot be modified
throughout the lifetime of the subscription. In order to cancel a subscription,
the client cancels the Subscribe
RPC associated with the subscription, or
terminates the entire gRPC session.
Subscriptions are fundamentally a set of independent update messages relating to
the state of the data tree. That is, it is not possible for a client requesting
a subscription to assume that the set of update messages received represent a
snapshot of the data tree at a particular point in time. Subscriptions therefore
allow a client to:
- Receive ongoing updates from a target which allow synchronization between
the client and target for the state of elements within the data tree. In
this case (i.e., aSTREAM
subscription), a client creating a subscription
receives an initial set of updates, terminated by a message indicating that
initial synchronisation has completed, and then receives subsequent updates
indicating changes to the initial state of those elements. - Receive a single view (polled, or one-off) for elements of the data tree on
a per-data element basis according to the state that they are in at the time
that the message is transmitted. This can be more resource efficient for
both target and client than aGetRequest
for large subtrees within the
data tree. The target does not need to coalesce values into a single
snapshot view, or create an in-memory representation of the subtree at the
time of the request, and subsequently transmit this entire view to the
client.
Based on the fact that subsequent update messages are considered to be
independent, and to ensure that the efficiencies described above can be
achieved, by default a target MUST NOT aggregate values within an update
message.
In some cases, however, elements of the data tree may be known to change
together, or need to be interpreted by the subscriber together. Such data MUST
be explicitly marked in the schema as being eligible to be aggregated when being
published. Additionally, the subscribing client MUST explicitly request
aggregation of eligible schema elements for the subscription - by means of the
allow_aggregation
flag within a SubscriptionList
message. For elements
covered by a subscription that are not explicitly marked within the schema as
being eligible for aggregation the target MUST NOT coalesce these values,
regardless of the value of the allow_aggregation
flag.
When aggregation is not permitted by the client or the schema each update
message MUST contain a (key, value) pair - where the key MUST be a path to a
single leaf element within the data tree (encoded according to Section
2.2.2). The value MUST encode only the value of the leaf specified.
In most cases, this will be a scalar value (i.e., a JSON value if a JSON
encoding is utilised), but in some cases, where an individual leaf element
within the schema represents an object, it MAY represent a set of values (i.e.,
a JSON object or Protobuf message).
Where aggregation is permitted by both the client and schema, each update
message MUST contain a key value pair, where the key MUST be the path to the
element within the data tree which is explicitly marked as being eligible for
aggregation. The value MUST be an object which encodes the children of the data
tree element specified. For JSON, the value is therefore a JSON object, and for
Protobuf is a binary-encoded Protobuf message (along with any child messages).
3.5.1 Managing Subscriptions
3.5.1.1 The SubscribeRequest Message
A SubscribeRequest
message is sent by a client to request updates from the
target for a specified set of paths.
The fields of the SubscribeRequest
are as follows:
- A group of fields, only one of which may be specified, which indicate the
type of operation that theSubscribeRequest
relates to. These are:subscribe
- aSubscriptionList
message specifying a new set of paths
that the client wishes to subscribe to.poll
- aPoll
message used to specify (on an existing RPC) that the
client wishes to receive a polled update for the paths specified within
the subscription. The semantics of thePoll
message are described in
Section 3.5.1.5.3.
extension
- a repeated field used to carry gNMI extensions, as per the
description in Section 2.8.
In order to create a new subscription a client MUST initiate a Subscribe
RPC
with a SubscribeRequest
message specifying the subscribe
field. The
SubscriptionList
may create a one-off subscription, a poll-only subscription,
or a streaming subscription. In the case of ONCE subscriptions, the RPC MUST be
closed following the initial response generation with the relevant status code.
Subscriptions are set once, and subsequently not modified by a client. If a
client wishes to subscribe to additional paths from a target, it MUST do so by
sending an additional Subscribe
RPC call, specifying a new SubscriptionList
message. In order to end an existing subscription, a client simply cancels the
Subscribe
RPC that relates to that subscription. If an RPC is initiated with
a SubscribeRequest
message that does not specify a SubscriptionList
message
with the request
field, the target MUST consider this an error. If an
additional SubscribeRequest
message specifying a SubscriptionList
is sent
via an existing RPC, the target MUST respond to this message with
SubscribeResponse
message indicating an error status, with a code of
InvalidArgument (4)
; other Subscribe
RPCs on the gRPC session MUST not be
modified or terminated.
If a client initiates a Subscribe
RPC with a SubscribeRequest
message which
does not contain a SubscriptionList
message, this is an error. A
SubscribeResponse
message with the status indicating a error code of
InvalidArgument
MUST be sent, and the RPC closed. The status message SHOULD
indicate that an out-of-order operation was requested on a non-existent
subscription.
3.5.1.2 The SubscriptionList Message
A SubscriptionList
message is used to indicate a set of paths for which common
subscription behavior are required. The fields of the message are:
subscription
- a set ofSubscription
messages that indicate the set of
paths associated with the subscription list.mode
- the type of subscription that is being created. This may beONCE
(described in 3.5.1.5.1);STREAM
(described
in 3.5.1.5.2); orPOLL
(described in
3.5.1.5.3). The default value for the mode
field isSTREAM
.prefix
- a common prefix that is applied to all paths specified within the
message as per the definition in Section 2.4.1. The
default prefix is null.qos
- a field describing the packet marking that is to be utilised for the
responses to the subscription that is being created. This field has a single
sub-value,marking
, which indicates the DSCP value as a 32-bit unsigned
integer. If theqos
field is not specified, the device should export
telemetry traffic using its default DSCP marking for management-plane
traffic.allow_aggregation
- a boolean value used by the client to allow schema
elements that are marked as eligible for aggregation to be combined into
single telemetry update messages. By default, aggregation MUST NOT be used.use_models
- aModelData
message (as specified in Section
2.6.1) specifying the schema definition modules
that the target should use when creating a subscription. When specified, the
target MUST only consider data elements within the defined set of schema
models as defined in Section 2.6. When
use_models
is not specified, the target MUST consider all data elements
that are defined in all schema modules that it supports.updates_only
- a boolean that causes the server to send only updates to
the current state. When set to true, the target MUST not transmit the
current state of the paths that the client has subscribed to, but rather
should send only updates to them. ForSTREAM
subscriptions, an update
occurs upon the next sample (in the case ofSAMPLE
subscriptions), or upon
the next value change forON_CHANGE
subscriptions. ForPOLL
andONCE
subscriptions, the target should send only thesync_response
message,
before proceeding to process poll requests (in the case ofPOLL
) or
closing the RPC (in the case ofONCE
)."extension
- a repeated field used to carry gNMI extensions, as per the
description in Section 2.8.
A client generating a SubscriptionList
message MUST include the subscription
field - which MUST be a non-empty set of Subscription
messages, all other
fields are optional.
3.5.1.3 The Subscription Message
A Subscription
message generically describes a set of data that is to be
subscribed to by a client. It contains a path
, specified as per the definition
in Section 2.2.2.
There is no requirement that the path specified in the message must exist within
the current data tree on the server. While the path within the subscription
SHOULD be a valid path within the set of schema modules that the target
supports, subscribing to any syntactically valid path within such modules MUST
be allowed. In the case that a particular path does not (yet) exist, the target
MUST NOT close the RPC, and instead should continue to monitor for the existence
of the path, and transmit telemetry updates should it exist in the future.
For POLL
and STREAM
subscriptions, a client may optionally specify
additional parameters within the Subscription
message. The semantics of these
additional fields are described in the relevant section of this document.
3.5.1.4 The SubscribeResponse Message
A SubscribeResponse
message is transmitted by a target to a client over an
established Subscribe
RPC. The message contains the following fields:
- A set of fields referred to as the
response
fields, only one of which can
be specified perSubscribeResponse
message:update
- aNotification
message providing an update value for a
subscribed data entity as described in Section
3.5.2.3.sync_response
- a boolean field indicating that all data values
corresponding to the path(s) specified in theSubscriptionList
has
been transmitted at least once, used forONCE
,POLL
andSTREAM
subscriptions.
extension
- a repeated field used to carry gNMI extensions, as per the
description in Section 2.8.
SubscribeResponse
messages with the update
field set to a Notification
are
not required to be sent by the target in timestamp order, and client
implementations MUST NOT assume that these messages will be received in
timestamp order.
3.5.1.5 Creating Subscriptions
3.5.1.5.1 ONCE Subscriptions
A subscription operating in the ONCE
mode acts as a single request/response
channel. The target creates the relevant update messages, transmits them, and
subsequently closes the RPC.
In order to create a one-off subscription, a client sends a SubscribeRequest
message to the target. The subscribe
field within this message specifies a
SubscriptionList
with the mode field set to ONCE
. Updates corresponding to
the subscription are generated as per the semantics described in Section
3.5.2.
Following the transmission of all updates which correspond to data items within
the set of paths specified within the subscription list, a SubscribeResponse
message with the sync_response
field set to true
MUST be transmitted, and
the RPC via which the SubscribeRequest
was received MUST be closed.
3.5.1.5.2 STREAM Subscriptions
Stream subscriptions are long-lived subscriptions which continue to transmit
updates relating to the set of paths that are covered within the subscription
indefinitely.
A STREAM
subscription is created by sending a SubscribeRequest
message with
the subscribe field containing a SubscriptionList
message with the type
specified as STREAM
. Each entry within the Subscription
message is specified
with one of the following modes
:
- On Change (
ON_CHANGE
) - when a subscription is defined to be “on
change”, data updates are only sent when the value of the data item changes.- For all
ON_CHANGE
subscriptions, the target MUST first generate updates
for all paths that match the subscription path(s), and transmit them.
Following this initial set of updates, updated values SHOULD only be
transmitted when their value changes. - A heartbeat interval MAY be specified along with an “on change”
subscription - in this case, the value of the data item(s) MUST be re-sent
once per heartbeat interval regardless of whether the value has changed or
not.
- For all
- Sampled (
SAMPLE
) - a subscription that is defined to be sampled MUST
be specified along with asample_interval
encoded as an unsigned 64-bit
integer representing nanoseconds between samples. The value of the data
item(s) MUST be sent once per sample interval to the client. If the target
is unable to support the desiredsample_interval
it MUST reject the
subscription by closing theSubscribe
RPC specifying anInvalidArgument (3)
error code. If thesample_interval
is set to 0, the target MUST
create the subscription and send the data with the lowest interval possible
for the target.- Optionally, the
suppress_redundant
field of theSubscription
message
may be set for a sampled subscription. In the case that it is set to
true
, the target SHOULD NOT generate a telemetry update message unless
the value of the path being reported on has changed since the last
update was generated. Updates MUST only be generated for those
individual leaf nodes in the subscription that have changed. That is to
say that for a subscription to/a/b
- where there are leavesc
and
d
branching from theb
node - if the value ofc
has changed, but
d
remains unchanged, an update ford
MUST NOT be generated, whereas
an update forc
MUST be generated. - A
heartbeat_interval
MAY be specified to modify the behavior of
suppress_redundant
in a sampled subscription. In this case, the
target MUST generate one telemetry update per heartbeat interval,
regardless of whether thesuppress_redundant
flag is set totrue
.
This value is specified as an unsigned 64-bit integer in nanoseconds.
- Optionally, the
- Target Defined
(TARGET_DEFINED)
- when a client creates a subscription
specifying the target defined mode, the target MUST determine the best type
of subscription to be created on a per-leaf basis. That is to say, if the
path specified within the message refers to some leaves which are event
driven (e.g., the changing of state of an entity based on an external
trigger) then anON_CHANGE
subscription may be created, whereas if other
data represents counter values, aSAMPLE
subscription may be created.
3.5.1.5.3 POLL Subscriptions
Polling subscriptions are used for on-demand retrieval of data items via
long-lived RPCs. A poll subscription relates to a certain set of subscribed
paths, and is initiated by sending a SubscribeRequest
message with
encapsulated SubscriptionList
. Subscription
messages contained within the
SubscriptionList
indicate the set of paths that are of interest to the polling
client.
To retrieve data from the target, a client sends a SubscribeRequest
message
to the target, containing a poll
field, specified to be an empty Poll
message. On reception of such a message, the target MUST generate updates for
all the corresponding paths within the SubscriptionList
. Updates MUST be
generated according to Section 3.5.2.3.
3.5.2 Sending Telemetry Updates
3.5.2.1 Bundling of Telemetry Updates
Since multiple Update
messages can be included in the Notification
message
of a SubscribeResponse
, it is possible for a target to bundle messages such
that fewer messages are sent to the client. The advantage of such bundling is
clearly to reduce the number of bytes on the wire (caused by message overhead);
however, since only Notification
messages contain the timestamp at which an
event occurred, or a sample was taken, such bundling assigns a single timestamp
for all bundled Update
values. As such, bundling is primarily useful for
datasets where a group of leaves are meaningfully conjoined, such as a group
of leaves atomically applied as a configuration update via a Set
call, system
properties that are effectively static after boot and component inventory data
including part, model and serial numbers.
For counter and event data where hardware provides precise timestamps, a
gNMI implementation MUST NOT obscure access to these timestamps in an
attempt to provide bundling. In cases where a leaf’s value is derived
from two or more hardware values with distinct timestamps, an implementation
SHOULD attempt to provide a consistent and meaningful timestamp that
introduces minimal error. This could include approaches such as attempting to synchronize collection
of the values, retaining a consistent sample period and having a robust
mechanism to ensure that sampling artifacts are not introduced (e.g. a constant
rate byte flow over an interface appearing to have adjacent spikes and dips).
3.5.2.3 Sending Telemetry Updates
When an update for a subscribed telemetry path is to be sent, a
SubscribeResponse
message is sent from the target to the client, on the RPC
associated with the subscription. The update
field of the message contains a
Notification
message as per the description in Section
2.1. The timestamp
field of the
Notification
message MUST be set to the time at which the value of the path
that is being updated was collected from the underlying data source, or the
event being reported on (in the case of ON_CHANGE
occurred).
Where a leaf node’s value has changed, or a new node has been created, an
Update
message specifying the path and value for the updated data item MUST be
appended to the update
field of the message.
Where a node within the subscribed paths has been removed, the delete
field of
the Notification
message MUST have the path of the node that has been removed
appended to it.
Explicit deletion is required to signify the removal of a leaf that is no longer
present on a target device in ON-CHANGE subscription mode, and optional in SAMPLE subscription mode.
Additionally, deletes are not required to be per-leaf and can be at an intermediate
branch that applies to a multitude of leaves, e.g. when removing a logical interface
in a configuration, deletes could be issued at container level branches that apply to
that interface, rather than all the individual leaves.
Explicit deletion also applies to TARGET-DEFINED subscription mode.
Whereas, if the TARGET-DEFINED subscription determines the best type of delivery to be ON-CHANGE,
explicit deletion is required and if decided to be SAMPLE, deletion will be optional.
To replace the contents of an entire node within the tree, the target populates
the delete
field with the path of the node being removed, along with the new
contents within the update
field.
To signal that a leaf that has transitioned to using its default
value, the target
MUST send an update
with the new value being set to the default value, and
MUST NOT only send a delete
for the path or a parent path.
When the target has transmitted the initial updates for all paths specified
within the subscription, a SubscribeResponse
message with the sync_response
field set to true
MUST be transmitted to the client to indicate that the
initial transmission of updates has concluded. This provides an indication to
the client that all of the existing data for the subscription has been sent at
least once. For STREAM
subscriptions, such messages are not required for
subsequent updates. For POLL
subscriptions, after each set of updates for
individual poll request, a SubscribeResponse
message with the sync_response
field set to true
MUST be generated.
In the case where the updates_only
field in the SubscribeRequest
message has
been set, a sync_response
is sent as the first message on the stream, followed
by any updates representing subsequent changes to current state. For a POLL
or
ONCE
mode, this means that only a sync_response
will be sent. The
updates_only
field allows a client to only watch for changes, e.g. an update
to configuration.
3.5.2.4 SubscribeResponse Behavior Table
The following table clarifies the target behaviors for Subscribe
for certain scenarios:
Subscription Scenario | ONCE/POLL | STREAM |
---|---|---|
Subscribed paths exist or a YANG default value is in use. | Value(s) are returned | Value(s) are returned |
Subscribed paths are syntactically correct but one or more paths neither exist (yet) nor has a YANG default value in use. | No value returned for non-existent paths | nothing is sent for non-existent paths (yet), RPC is not closed |
Subscribed paths are syntactically correct but one or more paths is not implemented by the server. | Return UNIMPLEMENTED |
Return UNIMPLEMENTED |
One or more subscribed paths is syntactically incorrect. | Return INVALID_ARGUMENT |
Return INVALID_ARGUMENT |
4 Appendix: Current Protobuf Message and Service Specification
The latest Protobuf IDL gNMI specification is found in GitHub at
openconfig/gnmi.
5 Appendix: Current Outstanding Issues/Future Features
- Ability for the client to exclude paths from a subscription or get.
- “Dial out” for the target to register with an NMS and publish pre-configured
subscriptions.
6 Copyright
Copyright 2016 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License
7 Revision History
-
v0.10.0: May 25, 2023
- Add
union_replace
operation. Sync revision to gNMI proto revision.
- Add
-
v0.8.3: April 18, 2023
- Clarify that
SetRequest
replace
on a list element with{}
is invalid.
- Clarify that
-
v0.8.2: November 28, 2022
- Clarify difference between
SetRequest
update
vs.replace
when updating
a keyed list. - Add gNMI service compatibility version.
- Clarify difference between
-
v0.8.1: July 7, 2022
- Clarify that for
Subscribe
, a transition to a YANG default value for a
leaf must useupdate
rather than just adelete
. - Clarify that for
Set
, deleting configuration usingreplace(nil)
is
prohibited. - Clarify target behavior for certain scenarios for
Get
andSubscribe
.
- Clarify that for
-
v0.8.0: April 28, 2022
- Add ‘double_val’ in TypedValue message to replace both ‘float_val’ and
decimal64_val. - Clarify format of responses when PROTO encoding is selected.
- Add ‘double_val’ in TypedValue message to replace both ‘float_val’ and
-
v0.7.0: May 22, 2018
- Add ‘atomic’ boolean option to Notification message.
-
v0.6.0: January 25, 2018
- Add
extension
fields to the top-level RPCs of the gNMI service. - Add recommendation that the gNMI service registers with the gRPC reflection
service. - Clarifying wording for ‘channel’ such that it refers to a specific RPC,
adopting gRPC nomenclature. - Editorial amendments.
- Add
-
v0.5.0: November 14, 2017
- Add
target
field withinPath
message with description in Section
2.2.2.1 - Add
updates_only
field withinSubscribeRequest
message. - Add
duplicates
field withingUpdate
message.
- Add
-
v0.4.0: June 16, 2017
- Deprecate the old
value
field within theUpdate
message, in favour of
the newTypedValue
field. - Clarify error handling should use
google/rpc/status.proto
rather than
embedded messages within successful response codes. - Update references to the
path
message’s encoding of the root path. - Update encoding of
Path
to use thePathElem
message rather than to use a
repeatedstring
.
- Deprecate the old
-
v0.2.2: March 7, 2017
- Add clarifications of
ON_CHANGE
subscriptions and the requirement for an
initial sync of matching subscription paths. - Correct responses to an unsupported encoding error to be
Unimplemented
(fixes #36).
- Add clarifications of
-
v0.2.1: November 10, 2016
-
Correct reference to
TEXT
vs.ASCII
encoding type. -
Ensure that the encodings enumeration is numbered consistently.
-
Fix broken links.
Notes
-
This matches the types that Go UnixNano and Java TimeUnit toNanos return,
and hence is used rather than an unsigned integer. ↩︎