Networked Media Open Specifications
HOME DOCS SPEC... VERSIONS... GITHUB INFO... TOOLS... IS-XX... MORE... SEARCH

Behaviour: Querying

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

(c) AMWA 2016, CC Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)

The Query API provides a read-only interface to the Nodes and their sub-resources which are currently held in the registry. Browsing of the Query API may be performed via the RESTful API, or by using the websocket protocol (RFC 6455) which is suggested for most applications.

API Resources

Where the behaviour associated with an API attribute is not sufficiently clear from its name and schema constraints, this is documented below.

Subscriptions

secure Indicates whether the WebSocket connection is provided via an encrypted connection or not (ws:// vs. wss://). Unless otherwise indicated the value of this attribute SHOULD be ‘false’ if the API is being presented via HTTP, and ‘true’ for HTTPS. Query API clients MAY choose to specify the opposite value in requests for subscriptions, however they will receive a 400 response code unless the Query API explicitly supports a mismatch between encrypted HTTP and WebSocket connections.

Creating a Websocket subscription

In order to connect to a websocket, a client must first request a subscription of a particular type and with particular query parameters by performing a POST as defined in the Query API subscriptions documentation. Use of GET requests to find existing suitable websocket connections is strongly discouraged.

There is no mandated URL base path for servers to use when creating 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.

Websockets created for specific clients will be cleaned up automatically if they disconnect.

Connection upgrade procedures permitting an existing HTTP query to transition to a websocket are not currently supported, but may be in the future.

Query API Behaviour

Long-lived connections to the Query API are supported via Websockets which can be set up via the /subscriptions resource. Query APIs may additionally support the HTTP ‘Upgrade’ header sent by clients to upgrade an HTTP GET request to a Websocket. In cases where this is performed, a corresponding entry in /subscriptions must also be created with matching query parameters.

Upon receiving a request for a new subscription, the Query API should identify whether it already has any websockets open which provide for the requested query. If a websocket exists, the ‘subscription’ object representing it may be returned to the user. If a relevant websocket does not exist a new one should be created.

In normal operation, once a websocket has no more clients subscribed to it the Query API may automatically remove it and its corresponding HTTP-advertised subscription object. The Query API MUST NOT acknowledge HTTP DELETE requests for websockets running in this ‘non-persistent’ mode, instead issuing an HTTP 403 response.

If a ‘persistent’ websocket has been requested by the client, this must not be cleaned up automatically by the Query API, even if all consuming clients have disconnected. The user may request closing of this socket by issuing an HTTP DELETE. If an HTTP DELETE is issued prior to all websocket connections being closed, they should be forcibly closed by the server.

Websocket Protocol

Using data Grains, the websocket protocol provides a client with the current state of the contents of the registry at the time of subscription. It subsequently notifies clients of any changes.

Note that the Source ID used in the following examples references the Query API instance. The Flow ID then corresponds to the subscription ID created via the /subscriptions HTTP resource.

The timestamps used in these messages relate to the NMOS Content Model. In this use case the three timestamps are permitted to be identical.

The ‘rate’ and ‘duration’ attributes may be ignored by clients as the event messages being exchanged do not adhere to a defined rate or duration.

Each Grain may contain one or more objects in its ‘data’ array. Each object identifies a change to a single Source, Flow or other resource as identified by the ‘topic’.

A schema for the Grain metadata described below is available here.

Resource(s) Added Event

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

{
  "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",
        "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(s) Removed Event

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

{
  "grain_type": "event",
  "source_id": <id_of_query_service_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",
        "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(s) Modified Event

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": "event",
  "source_id": <id_of_query_service_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",
        "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(s) Unchanged (Sync) Event

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

{
  "grain_type": "event",
  "source_id": <id_of_query_service_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",
        "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 the same way as the corresponding REST API endpoints. Care should be taken to ensure that clients are informed when resources begin to or no longer match a given query parameter. For example:

Referential Integrity

API clients should be aware of the following potential issues when interacting with the ‘senders’ and ‘receivers’ arrays present within Device resources. Use of these arrays is discouraged.

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