Networked Media Open Specifications
SPEC... VERSIONS... REPO INFO... TOOLS... IS-... BCP-... MORE... SEARCH

Behaviour: Querying

←Behaviour - Registration · Index↑ · Behaviour - Nodes→

The Query API provides a read-only interface to the Nodes and their sub-resources which are currently held in the registry. Monitoring of these resources can be performed using the HTTP API, or using a WebSocket connection (RFC 6455), which is suggested for most applications.

API Resources

Additional requirements for behaviour associated with particular attributes, beyond what is specified in the schemas, are documented below.

Subscriptions

secure: Indicates whether the WebSocket connection is encrypted (ws:// vs. wss://). If the client does not specify in the request to create the Subscription, the server SHOULD assign the value false if the API is being presented via HTTP, and true for HTTPS. Query API clients MAY specify the opposite value in requests for Subscriptions, however they will receive a 400 (Bad Request) response code unless the Query API explicitly supports a mismatch between encrypted and insecure HTTP and WebSocket connections.

authorization: Indicates whether the WebSocket connection requires authorization in order to connect. Use of authorization is likely to be a deployment decision and be the same for all Subscriptions exposed from a single Query API, and for the HTTP API itself. Query API clients MAY specify a requested value for this attribute, but in most circumstances this will result in a 400 (Bad Request) response code if the Query API is operating in the opposite mode.

persist: Indicates whether the Subscription is persistent or non-persistent. The Query API MAY remove any Subscriptions with persist set to false that no longer have WebSocket connections. The Query API MUST NOT acknowledge HTTP DELETE requests for Subscriptions running in this non-persistent mode, instead issuing an HTTP 403 (Forbidden) response. If a persistent Subscription has been requested by the client, this MUST NOT be cleaned up automatically by the Query API, even if all clients have disconnected. If an HTTP DELETE is issued prior to all WebSocket connections being closed, they SHOULD be forcibly closed by the server.

Creating a WebSocket Subscription

In order to connect to a WebSocket, a client first requests a Subscription of a particular resource type and with particular query parameters by performing a POST request to the /subscriptions resource, as defined in the Query API specification. Use of GET requests to find existing suitable Subscriptions is strongly discouraged.

Upon receiving a request for a new Subscription, the Query API MAY return an existing Subscription to the user, if it matches the requested attributes. If a relevant Subscription does not exist, a new one SHOULD be created.

As for the HTTP API endpoints, a 501 (Not Implemented) HTTP status indicates that the requested query parameters are not supported by this Query API.

There is no mandated URL base path for servers to use to provide WebSocket connections. Instead clients SHOULD observe the value of ws_href which is returned by their Subscription request in order to identify what to connect to.

Query APIs MAY additionally support the HTTP protocol upgrade mechanism on list resources such as /nodes to transition an HTTP GET request to a WebSocket connection, but this is not mandated. In cases where this is performed, a corresponding entry in /subscriptions for a non-persistent Subscription MUST also be created with matching attributes.

WebSocket Messages

The server provides a client with the current state of the contents of the registry at the time of their WebSocket connection, using messages which are known as data Grains. It subsequently notifies clients of any changes via additional data Grain messages.

In the Query API usage, the source_id in each message identifies the Query API instance. The flow_id is the id of the Subscription under the /subscriptions HTTP resource.

The timestamps used in data Grain messages are as follows:

The three timestamps MAY be identical. For more details of the timing model used in NMOS specifications, see MS-04.

The rate and duration attributes MAY be ignored by clients as the messages being exchanged represent events in the registry and do not adhere to a defined rate or duration.

Each Grain MAY contain one or more objects in its data array. Each event object identifies a change to a single Source, Flow or other resource as identified by the Grain topic and the event path, which together correspond to the resource path in the Query API.

A data Grain message related to the subscription e223e6f3-de75-4855-bd19-b83774e31689, with an event corresponding to the Query API resource /flows/b58aae65-1913-4f7b-aae2-2377446dd639.

{
  "grain_type": "event",
  "source_id": "<id_of_query_api_instance>",
  "flow_id": "e223e6f3-de75-4855-bd19-b83774e31689",
  "origin_timestamp": "<ts_secs>:<ts_nsecs>",
  "sync_timestamp": "<ts_secs>:<ts_nsecs>",
  "creation_timestamp": "<ts_secs>:<ts_nsecs>",
  "rate": {
    "numerator": 0,
    "denominator": 1
  },
  "duration": {
    "numerator": 0,
    "denominator": 1
  },
  "grain": {
    "type": "urn:x-nmos:format:data.event",
    "topic": "/flows/",
    "data": [
      {
        "path": "b58aae65-1913-4f7b-aae2-2377446dd639",
        ...
      },
      ...
    ]
  }
}

A schema for the WebSocket messages is available here.

Resource Added Events

Event data containing only a post attribute signifies creation of a resource.

  "grain": {
    "type": "urn:x-nmos:format:data.event",
    "topic": "/flows/",
    "data": [
      {
        "path": "b58aae65-1913-4f7b-aae2-2377446dd639",
        "post": {
          "id": "b58aae65-1913-4f7b-aae2-2377446dd639",
          "label": "my_flow_name",
          "description": "my flow description",
          "source_id": "0e1b33f-6cfb-423e-b777-23efe0f539f4",
          "format": "urn:x-nmos:format:video"
        }
      },
      ...
    ]
  }

Resource Removed Events

Event data containing only a pre attribute signifies deletion of a resource.

  "grain": {
    "type": "urn:x-nmos:format:data.event",
    "topic": "/flows/",
    "data": [
      {
        "path": "b58aae65-1913-4f7b-aae2-2377446dd639",
        "pre": {
          "id": "b58aae65-1913-4f7b-aae2-2377446dd639",
          "label": "my_flow_name",
          "description": "my flow description",
          "source_id": "0e1b33f-6cfb-423e-b777-23efe0f539f4",
          "format": "urn:x-nmos:format:video"
        }
      },
      ...
    ]
  }

Resource Modified Events

Event data containing both pre and post attributes signifies modification of a resource. All attributes of the resource MUST be specified (i.e. not just those that have changed).

  "grain": {
    "type": "urn:x-nmos:format:data.event",
    "topic": "/flows/",
    "data": [
      {
        "path": "b58aae65-1913-4f7b-aae2-2377446dd639",
        "pre": {
          "id": "b58aae65-1913-4f7b-aae2-2377446dd639",
          "label": "my_flow_name",
          "description": "my flow description",
          "source_id": "0e1b33f-6cfb-423e-b777-23efe0f539f4",
          "format": "urn:x-nmos:format:video"
        },
        "post": {
          "id": "b58aae65-1913-4f7b-aae2-2377446dd639",
          "label": "my_new_flow_name",
          "description": "my new flow description",
          "source_id": "0e1b33f-6cfb-423e-b777-23efe0f539f4",
          "format": "urn:x-nmos:format:video"
        }
      },
      ...
    ]
  }

Resource Unchanged (Sync) Events

Event data containing both pre and post where the contents of pre and post are identical. This is used in initial synchronisation messages that ensure the client has received all data for a given topic.

  "grain": {
    "type": "urn:x-nmos:format:data.event",
    "topic": "/flows/",
    "data": [
      {
        "path": "b58aae65-1913-4f7b-aae2-2377446dd639",
        "pre": {
          "id": "b58aae65-1913-4f7b-aae2-2377446dd639",
          "label": "my_flow_name",
          "description": "my flow description",
          "source_id": "0e1b33f-6cfb-423e-b777-23efe0f539f4",
          "format": "urn:x-nmos:format:video"
        },
        "post": {
          "id": "b58aae65-1913-4f7b-aae2-2377446dd639",
          "label": "my_flow_name",
          "description": "my flow description",
          "source_id": "0e1b33f-6cfb-423e-b777-23efe0f539f4",
          "format": "urn:x-nmos:format:video"
        }
      },
      {
        "path": "e759c3f0-8eed-4344-932a-5eb1c40a2d41",
        "pre": {
          "id": "e759c3f0-8eed-4344-932a-5eb1c40a2d41",
          "label": "another_flow_name",
          "description": "another flow description",
          "source_id": "d7f43929-30c7-4847-a0f8-0242b82002d8",
          "format": "urn:x-nmos:format:audio"
        },
        "post": {
          "id": "e759c3f0-8eed-4344-932a-5eb1c40a2d41",
          "label": "another_flow_name",
          "description": "another flow description",
          "source_id": "d7f43929-30c7-4847-a0f8-0242b82002d8",
          "format": "urn:x-nmos:format:audio"
        }
      },
      ...
    ]
  }

Handling Query Parameters

WebSocket subscriptions support query parameters in a similar way as the corresponding HTTP API endpoints. Query parameters are specified in a params attribute rather than the query string. The Basic Queries documentation includes the examples:

GET /x-nmos/query/v1.0/sources?format=urn:x-nmos:format:video&device_id=9126cc2f-4c26-4c9b-a6cd-93c4381c9be5
GET /x-nmos/query/v1.0/flows?tags.studio=HQ1

The POST requests to create equivalent Subscriptions would have:

  "resource_path": "/sources",
  "params": {
    "format": "urn:x-nmos:format:video",
    "device_id": "9126cc2f-4c26-4c9b-a6cd-93c4381c9be5"
  }
  "resource_path": "/flows",
  "params": {
    "tags.studio": "HQ1"
  }

Subscriptions MUST inform clients when resources begin to match, or no longer match, the given query parameters. For example:

Referential Integrity

The senders and receivers arrays in Device resources are now deprecated, as referential integrity issues could occur if:

Use of these arrays is discouraged and Node/Query API clients SHOULD instead discover attached Senders/Receivers by filtering Senders and Receivers on device_id.

←Behaviour - Registration · Index↑ · Behaviour - Nodes→