<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
<?rfc toc="yes"?>
<?rfc tocompact="yes"?>
<?rfc tocdepth="2"?>
<?rfc tocindent="yes"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes"?>
<?rfc comments="yes"?>
<?rfc inline="yes"?>
<?rfc compact="yes"?>
<?rfc subcompact="no"?>
<rfc category="info" docName="draft-voit-restconf-yang-push-00"
     ipr="trust200902">
  <front>
    <title abbrev="Restconf Push">Restconf subscription and HTTP push for YANG
    datastores</title>

    <author fullname="Eric Voit" initials="E." surname="Voit">
      <organization>Cisco Systems</organization>

      <address>
        <email>evoit@cisco.com</email>
      </address>
    </author>

    <author fullname="Alexander Clemm" initials="A" surname="Clemm">
      <organization>Cisco Systems</organization>

      <address>
        <email>alex@cisco.com</email>
      </address>
    </author>

    <author fullname="Ambika Prasad Tripathy" initials="A" surname="Tripathy">
      <organization>Cisco Systems</organization>

      <address>
        <postal>
          <street/>

          <city/>

          <region/>

          <code/>

          <country/>
        </postal>

        <phone/>

        <facsimile/>

        <email>ambtripa@cisco.com</email>

        <uri/>
      </address>
    </author>

    <author fullname="Einar Nilsen-Nygaard" initials="E"
            surname="Nilsen-Nygaard">
      <organization>Cisco Systems</organization>

      <address>
        <postal>
          <street/>

          <city/>

          <region/>

          <code/>

          <country/>
        </postal>

        <phone/>

        <facsimile/>

        <email>einarnn@cisco.com</email>

        <uri/>
      </address>
    </author>

    <author fullname="Alberto Gonzalez Prieto" initials="A"
            surname="Gonzalez Prieto">
      <organization>Cisco Systems</organization>

      <address>
        <postal>
          <street/>

          <city/>

          <region/>

          <code/>

          <country/>
        </postal>

        <phone/>

        <facsimile/>

        <email>albertgo@cisco.com</email>

        <uri/>
      </address>
    </author>

    <date day="13" month="October" year="2015"/>

    <area>Operations &amp; Management</area>

    <workgroup>NETCONF</workgroup>

    <keyword>Draft</keyword>

    <abstract>
      <t>This document defines Restconf subscription and push mechanisms to
      continuously stream information from YANG datastores over HTTP. These
      mechanisms allow client applications or operations support systems to
      request custom sets of updates from a YANG datastore. This document also
      specifies how to stream updates over HTTP without Restconf. In either
      case, updates are pushed by a datastore to a receiver per a subscription
      policy, without requiring continuous requests.</t>
    </abstract>
  </front>

  <middle>
    <section title="Introduction">
      <t>Requirements for subscriptions to YANG datastores are defined in
      <xref target="pub-sub-reqs"/>. Mechanisms to support YANG subscriptions
      and datastore object push over a NETCONF are defined in <xref
      target="netconf-yang-push"/>. Restconf support of subscriptions, with
      HTTP transport of pushed updates is also needed by the market. This
      document provides such a specification.</t>

      <t>Key benefits of pushing data via HTTP include:</t>

      <t><list style="symbols">
          <t>Ability to configure static subscriptions on a Publisher</t>

          <t>Ability for the Publisher to initiate communications with the
          Receiver</t>

          <t>Ability of a Subscriber to be different from the Receiver</t>
        </list>There are also additional benefits which can be realized when
      pushing updates via HTTP/2 <xref target="RFC7540"/>:</t>

      <t><list style="symbols">
          <t>Subscription multiplexing over independent HTTP/2 streams</t>

          <t>Stream prioritization</t>

          <t>Stream dependencies</t>

          <t>Flow control on independent streams</t>

          <t>Header compression</t>
        </list>These additional benefits will address issues resulting from
      head-of-line blocking and relative subscription priority.</t>

      <t>To maximize transport independence of YANG subscription methods, this
      document reuses many capabilities of <xref
      target="netconf-yang-push"/>[] including:</t>

      <t><list style="symbols">
          <t>Operations for creating, modifying and deleting subscriptions</t>

          <t>Syntax and parameters for negotiating the subscription</t>

          <t>YANG data model to manage subscriptions</t>

          <t>Mechanisms to communicate subscription filters and data
          streams</t>
        </list></t>
    </section>

    <section title="Terminology">
      <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
      "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
      document are to be interpreted as described in <xref
      target="RFC2119">RFC 2119</xref>.</t>

      <t>Datastore: a conceptual store of instantiated management information,
      with individual data items represented by data nodes which are arranged
      in hierarchical manner.</t>

      <t>Dynamic YANG Subscription: Subscription negotiated with Publisher via
      create, modify, and delete control plane signaling messages.</t>

      <t>Publisher: an entity responsible for distributing subscribed YANG
      object data per the terms of a Subscription. In general, a Publisher is
      the owner of the YANG datastore that is subjected to the
      Subscription.</t>

      <t>Receiver: the target where a Publisher pushes updates. In many
      deployments, the Receiver and Subscriber will be the same entity.</t>

      <t>Static YANG Subscription: A Subscription installed via a
      configuration interface.</t>

      <t>Subscriber: An entity able to request and negotiate a contract for
      push updates from a Publisher.</t>

      <t>Subscription: A contract between a Subscriber and a Publisher,
      stipulating which information the Receiver wishes to have pushed from
      the Publisher without the need for further solicitation.</t>

      <t>Subscription Update: Set of data nodes and object values pushed
      together as a unit and intended to meet the obligations of a single
      subscription at a snapshot in time.</t>
    </section>

    <section title="Solution">
      <t>This document specifies mechanisms that allow subscribed information
      updates to be pushed from a YANG datastore. Subscriptions may either be
      initiated via requests by Subscribers, or statically configured on a
      Publisher. As in <xref target="netconf-yang-push"/>, Publisher must
      respond to a subscription request explicitly positively or negatively.
      Negative responses will include information about why the Subscription
      was not accepted, in order to facilitate converging on an acceptable set
      of Subscription parameters.</t>

      <t>Once a Subscription has been established, updates are pushed to the
      Receiver until the Subscription terminates. Based on parameters within
      the Subscription, these updates can be streamed immediately as any
      subscribed objects change, or sent periodically.</t>

      <section title="Subscription Model">
        <t>Subscriptions use the base data model from <xref
        target="netconf-yang-push"/>. This model is extended with several
        optional parameters for Subscription Priority and Subscription
        Dependency. These parameters allow a Subscriber or other configuration
        interface to assert how it prefers the Publisher allocate resources
        when handling multiple Subscriptions. These parameters are intended to
        be used in conjunction with the transport layer. Specifically, when a
        new Subscription is being established with an underlying transport is
        HTTP/2, these parameters may be directly mapped into HTTP/2 to
        prioritize transport and to assist with flow control of individual
        streams.</t>
      </section>

      <section title="Subscription states at Publisher">
        <t>Below is the state machine for the Publisher. It is important to
        note that a Subscription doesn&rsquo;t exist at the Publisher until it
        is accepted and made active. The assertion of a
        &lt;create-subscription&gt; by a Subscriber is insufficient for that
        asserted subscription to be externally visible via this state
        machine.</t>

        <figure>
          <preamble>Subscription states at Publisher</preamble>

          <artwork><![CDATA[                 .-------.
                 | start |
                 '-------'
                     |
                  create
                     |
                     |   .----------modify-------------.
                     v   v                              '
               .-----------.                      .-----------.
    .--------. |           |------>suspend------->|           |
  modify      '|  active   |                      | suspended |
    '--------->|           |<----reactivate<------|           |
               '-----------'                      '-----------'
                     |                                  |
                  delete                             delete
                     |                                  |
                     v                                  |
                 .-------.                              |
                 |  end  |<-----------------------------'
                 '-------']]></artwork>
        </figure>

        <t>Of interest in this state machine are the following:</t>

        <t><list style="symbols">
            <t>Successful &lt;create-subscription&gt; or
            &lt;modify-subscription&gt; actions must put the subscription into
            an active state.</t>

            <t>Failed &lt;modify-subscription&gt; actions will leave the
            subscription in its previous state, with no visible change to any
            streaming updates.</t>

            <t>A &lt;delete-subscription&gt; action will delete the entire
            subscription.</t>
          </list></t>
      </section>

      <section title="Mechanisms for Subscription Establishment and Maintenance">
        <t>On a Publisher, it must be possible to instantiate a Subscription
        via dynamic Subscriber signaling, as well as via Static
        configuration.</t>

        <t>Dynamic YANG Subscriptions are signaled Subscriptions aimed at the
        running datastore and are unable to impact the startup configuration.
        They should always terminate when there is loss of transport session
        connectivity between the Publisher and Receiver.</t>

        <t>Static Subscriptions are applied via an operations interface to the
        startup and running configurations. Loss or non-availability of
        transport session connectivity will place the Subscription into the
        suspended state. Logic beyond the scope of this specification will
        dictate when any particular Subscription should be reactivated. There
        are three models for Subscription establishment and maintenance:</t>

        <t><list style="numbers">
            <t>Dynamic YANG Subscription: Subscriber and Receiver are the
            same</t>

            <t>Static YANG Subscription</t>

            <t>Dynamic YANG Subscription: Subscriber and Receiver are
            different</t>
          </list>The first two are described in this section. The third is
        described in <xref target="app.ex-if"/>. This third option can be
        moved into the body of this specification should the IETF community
        desire. In theory, all three models may be intermixed in a single
        deployment. Figure 2 shows such a scenario.</t>

        <figure>
          <artwork><![CDATA[                       .---------------.
                       |   Publisher   |
                       '---------------'
                         ^   ^   |   ^
                         |   |   |   |
       .-----Restconf----'   |   |   '-----Restconf----. 
       |               .-----'   '-HTTP-.              |
       V               |                V              |
.-------------.  .------------.  .----------.  .------------. 
| Subscriber+ |  | Operations |  | Receiver |  | Subscriber |
| Receiver    |  |  /Config   |  '----------'  '------------'
'-------------'  '------------'    ^     ^               ^
       ^         (out of scope)    :     :               :
       :             ^             :     :....Model 3....:
     Model 1         :...Model 2...:      (out of scope)]]></artwork>
        </figure>

        <section title="Dynamic YANG Subscription: Subscriber and Receiver are the same">
          <t>With all Dynamic YANG Subscriptions, as with <xref
          target="netconf-yang-push"/> it must be possible to configure and
          manage Subscriptions via signaling. This signaling is transported
          over <xref target="restconf"/>. Once established, streaming
          Subscription Updates are then delivered via Restconf SSE.</t>
        </section>

        <section title="Static YANG Subscription">
          <t>With a Static YANG Subscription, all information needed to
          establish a secure object push relationship with that Receiver must
          be configured via a configuration interface on the Publisher. This
          information includes all the &lt;create-subscription&gt; information
          identified in section 3.3.1. This information also includes the
          Receiver address, encoding selection, and any security credentials
          required to establish TLS between the Publisher and Receiver.
          Mechanisms for locally configuring these parameters are outside the
          scope of this document.</t>

          <t>With this information, the Publisher will establish a secure
          transport connection with the Receiver and then begin pushing the
          streaming updates to the Receiver. Since Restconf might not exist on
          the Receiver, it is not desirable to require that updates be pushed
          via Restconf. In place of Restconf, a TLS secured HTTP Client
          connection must be established with an HTTP Server located on the
          Receiver. Subscription Updates will then be sent via HTTP Post
          messages to the Receiver.</t>

          <t>Post messages will be addressed to HTTP augmentation code on the
          Receiver capable accepting and responding to Subscription Updates.
          At least the initial Post message must include the URI for the
          subscribed resource. This URI can be retained for future use by the
          Receiver.</t>

          <t>After successful receipt of an initial Subscription Update for a
          particular Subscription, this augmentation should reply back with an
          HTTP status code of 201 (Created). Further successful receipts
          should result in the return of code of 202 (Accepted). At any point,
          receipt of any status codes from 300-510 with the exception of 408
          (Request Timeout) should result in the movement of the Subscription
          to the suspended state. A sequential series of multiple 408
          exceptions should also drive the Subscription to a suspended
          state.</t>

          <t>Security on an HTTP client/Publisher can be strengthened by only
          accepting Response code feedback for recently initiated HTTP
          POSTs.</t>

          <t>Figure 3 depicts this message flow.</t>

          <figure>
            <artwork><![CDATA[   +-----------+                 +----------+
   | Publisher |                 | Receiver |
   +-----------+                 +----------+
        |<--------------TLS------------>|
        |                               | 
        |HTTP POST (Sub ID, URI, data1) |
        |------------------------------>|
        |             HTTP 201 (Created)|
        |<------------------------------| 
        |HTTP POST (Sub ID, data2)      | 
        |------------------------------>| 
        |     HTTP 200 or 202 (Accepted)| 
        |<------------------------------| 
        |             data3             | 
        |<----------------------------->| ]]></artwork>
          </figure>

          <t>If HTTP/2 transport is available to a Receiver, the Publisher
          should also:</t>

          <t><list style="symbols">
              <t>point individual Subscription Updates to a unique HTTP/2
              stream for that Subscription,</t>

              <t>take any subscription-priority and provision it into the
              HTTP/2 stream priority, and</t>

              <t>take any subscription-dependency and provision it into the
              HTTP/2 stream dependency.</t>
            </list></t>
        </section>
      </section>

      <section title="Negotiation of Subscription Policies">
        <t>When using signaling to create a Dynamic YANG Subscription,
        negotiable parameters will include the same negotiable parameters
        defined within <xref target="netconf-yang-push"/>.</t>

        <t>Additionally, negotiation may also include Subscription Priority. A
        Publisher may accept a Subscriber asserted Priority, as well as
        rejecting a subscription with a hint at what priority might be
        accepted.</t>
      </section>

      <section title="Support for Periodic and On-change">
        <t>Implementations must support periodic and/or on-change
        subscriptions as defined in <xref target="netconf-yang-push"/>.</t>
      </section>

      <section title="Filters and Streams">
        <t>Implementations must support filters and streams as defined in
        <xref target="netconf-yang-push"/>.</t>
      </section>

      <section title="Authorization">
        <t>Same authorization model for data as [netconf-yang-push] will be
        used. This includes functions of the Netconf Access Control Model
        <xref target="RFC6536"/> applied to objects to be pushed via
        Restconf.</t>

        <t>A Subscription (including a Static YANG Subscription) may only be
        established if the Subscriber or some entity statically configuring
        via the Publisher&rsquo;s operational interface has read access to the
        target data node.</t>
      </section>

      <section title="Subscription Multiplexing">
        <t>When pushed directly over HTTP/2, it is expected that each
        Subscription Update will be allocated a separate Stream. The will
        enable multiplexing, and address issues of Head-of-line blocking with
        different priority Subscriptions.</t>

        <t>When pushed via Restconf over HTTP/2, different Subscriptions will
        not be mapped to independent HTTP/2 streams. When Restconf specifies
        this mapping, it should be integrated into this specification.</t>

        <t>Even without HTTP/2 multiplexing, it is possible that updates might
        be delivered in a different sequence than generated. Reasons for this
        might include (but are not limited to):</t>

        <t><list style="symbols">
            <t>different durations needed to create various Subscription
            Updates,</t>

            <t>marshalling and bundling of multiple Subscription Updates for
            transport, and</t>

            <t>parallel HTTP1.1 sessions</t>
          </list>Therefore each Subscription Update will include a microsecond
        level timestamp to ensure that a receiver understands the time when a
        that update was generated. Use of this timestamp can give an
        indication of the state of objects at a Publisher when state-entangled
        information is received across different subscriptions. The use of the
        latest Subscription Update timestamp for a particular object update
        can introduce errors. So when state-entangled updates have
        inconsistent object values and temporally close timestamps, a Receiver
        might consider performing a &lsquo;get&rsquo; to validate the current
        state of objects.</t>
      </section>

      <section title="Push Data Stream and Transport Mapping">
        <t>Transported updates will contain data for one or more Subscription
        Updates. Each transported Subscription Update notification contains
        several parameters:</t>

        <t><list style="symbols">
            <t>A global subscription ID correlator, referencing the name of
            the Subscription on whose behalf the notification is sent.</t>

            <t>Data nodes containing a representation of the datastore subtree
            containing the updates. The set of data nodes must be filtered per
            access control rules to contain only data that the subscriber is
            authorized to see.</t>

            <t>An event time which contains the time stamp at publisher when
            the event is generated.</t>
          </list></t>

        <section title="Pushing Subscription Updates via Restconf">
          <t>Subscribers can dynamically learn whether a RESTCONF server
          supports yang-push. This is done by issuing an HTTP request OPTIONS,
          HEAD, or GET on the stream push-update. E.g.:</t>

          <figure>
            <artwork><![CDATA[GET /restconf/data/ietf-restconf-monitoring:restconf-state/
         streams/stream=yang-push HTTP/1.1
Host: example.com
Accept: application/yang.data+xml ]]></artwork>
          </figure>

          <t>If the server supports it, it may respond</t>

          <figure>
            <artwork><![CDATA[HTTP/1.1 200 OK
Content-Type: application/yang.api+xml
<stream xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf-monitoring">
            <name>yang-push</name>
            <description>Yang push stream</description>
            <access>
               <encoding>xml</encoding>
               <location>https://example.com/streams/yang-push-xml
               </location>
            </access>
            <access>
               <encoding>json</encoding>
               <location>https://example.com/streams/yang-push-json
               </location>
            </access>
         </stream>
]]></artwork>
          </figure>

          <t>If the server does not support yang push, it may respond</t>

          <figure>
            <artwork><![CDATA[HTTP/1.1 404 Not Found
Date: Mon, 25 Apr 2012 11:10:30 GMT
Server: example-server
]]></artwork>
          </figure>

          <t>Subscribers can determine the URL to receive updates by sending
          an HTTP GET request for the "location" leaf with the stream list
          entry. The stream to use for yang push is the push-update stream.
          The location returned by the publisher can be used for the actual
          notification subscription. Note that different encodings are
          supporting using different locations. For example, he subscriber
          might send the following request:</t>

          <figure>
            <artwork><![CDATA[GET /restconf/data/ietf-restconf-monitoring:restconf-state/
         streams/stream=yang-push/access=xml/location HTTP/1.1
Host: example.com
Accept: application/yang.data+xml
]]></artwork>
          </figure>

          <t>The publisher might send the following response:</t>

          <figure>
            <artwork><![CDATA[HTTP/1.1 200 OK
Content-Type: application/yang.api+xml
   <location
        xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf-monitoring">
        https://example.com/streams/yang-push-xml
   </location>
]]></artwork>
          </figure>

          <t>To subscribe and start receiving updates, the subscriber can then
          send an HTTP GET request for the URL returned by the publisher in
          the request above. The accept header must be "text/event -stream".
          The publisher handles the connection as an event stream, using the
          Server Sent Events<xref target="W3C-20121211"/> transport
          strategy.</t>

          <t>The publisher MUST support as query parameters for a GET method
          on this resource all the parameters of a subscription. The only
          exception is the encoding, which is embedded in the URI. An example
          of this is:</t>

          <figure>
            <artwork><![CDATA[// subtree filter = /foo
// periodic updates, every 5 seconds
GET /mystreams/yang-push?subscription-id=my-sub&period=5&
           xpath-filter=%2Fex:foo[starts-with("bar"."some"]
]]></artwork>
          </figure>

          <t>Should the publisher not support the requested subscription, it
          may reply:</t>

          <figure>
            <artwork><![CDATA[HTTP/1.1 501 Not Implemented
Date: Mon, 23 Apr 2012 17:11:00 GMT
Server: example-server
Content-Type: application/yang.errors+xml
    <errors xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf">
       <error>
           <error-type>application</error-type>
           <error-tag>operation-not-supported</error-tag>
           <error-severity>error</error-severity>
           <error-message>Xpath filters not supported</error-message>
           <error-info>
               <supported-subscription xmlns="urn:ietf:params:xml:ns:
                   netconf:datastore-push:1.0">
                   <subtree-filter/>
               </supported-subscription>
           </error-info>
       </error>
     </errors>

with an equivalent JSON encoding representation of:

HTTP/1.1 501 Not Implemented
Date: Mon, 23 Apr 2012 17:11:00 GMT
Server: example-server
Content-Type: application/yang.errors+json
      {
        "ietf-restconf:errors": {
          "error": {
            "error-type": "protocol",
            "error-tag": "operation-not-supported",
            "error-message": "Xpath filters not supported."
            "error-info": {
               "datastore-push:supported-subscription": {
                     "subtree-filter": [null]
                 }
            }
          }
        }
      }
]]></artwork>
          </figure>

          <t>The following is an example of a push Subscription Update data
          for the subscription above. It contains a subtree with root foo that
          contains a leaf called bar:</t>

          <figure>
            <artwork><![CDATA[XML encoding representation:
  <?xml version="1.0" encoding="UTF-8"?>  
  <notification xmlns="urn:ietf:params:xml:ns:yang:ietf-restconf">
     <subscription-id xmlns="urn:ietf:params:xml:ns:restconf:
         datastore-push:1.0">
           my-sub
     </subscription-id>
     <eventTime>2015-03-09T19:14:56Z</eventTime>
     <datastore-contents xmlns="urn:ietf:params:xml:ns:restconf:
        datastore-push:1.0">
        <foo xmlns="http://example.com/yang-push/1.0">
          <bar>some_string</bar>
        </foo>
     </datastore-contents>
  </notification>
]]></artwork>
          </figure>

          <t>Or with the equivalent YANG over JSON encoding representation as
          defined in<xref target="yang-json"/> :</t>

          <figure>
            <artwork><![CDATA[{
  "ietf-restconf:notification": {
    "datastore-push:subscription-id": "my-sub",
    "eventTime": "2015-03-09T19:14:56Z",
    "datastore-push:datastore-contents": {
      "example-mod:foo": { "bar": "some_string" }
    }
  }
}
]]></artwork>
          </figure>

          <t>To modify a subscription, the subscriber issues another GET
          request on the provided URI using the same subscription-id as in the
          original request. For example, to modify the update period to 10
          seconds, the subscriber may send:</t>

          <figure>
            <artwork><![CDATA[GET /mystreams/yang-push?subscription-id=my-sub&period=10&
       subtree-filter=%2Ffoo']]></artwork>
          </figure>

          <t>To delete a subscription, the subscriber issues a DELETE request
          on the provided URI using the same subscription-id as in the
          original request</t>

          <figure>
            <artwork><![CDATA[DELETE /mystreams/yang-push?subscription-id=my-sub]]></artwork>
          </figure>

          <t/>
        </section>

        <section title="Pushing Subscription Updates directly via HTTP">
          <t>For any version of HTTP, the basic encoding will look as below is
          the above JSON representation wrapped in an HTTP header. Mechanism
          will be</t>

          <figure>
            <artwork><![CDATA[POST (IP+Port) HTTP/1.1
From: (Identifier for Network Element)
User-Agent: (CiscoYANGPubSub/1.0)
Content-Type: multipart/form-data
Content-Length: (determined runtime)
{
  "ietf-yangpush:notification": {
    "datastore-push:subscription-id": "my-sub",
    "eventTime": "2015-03-09T19:14:56Z",
    "datastore-push:datastore-contents": {
      "foo": { "bar": "some_string" }
    }
  }
}
]]></artwork>
          </figure>

          <t/>
        </section>
      </section>

      <section title="YANG Tree">
        <t>Below is the object tree for the model. All items are imported from
        [netconf-yang-push] except for the addition of
        &ldquo;subscription-priority&rdquo; and
        &ldquo;subscription-dependency&rdquo;.</t>

        <figure>
          <artwork><![CDATA[   module: ietf-restconf-yang-push
   +-ro system-streams
   |  +-ro system-stream*                 system-stream
   +-rw filters
   |  +-rw filter* [filter-id]
   |     +-rw filter-id                   filter-id
   |     +-rw subtree-filter?             subtree-filter
   |     +-rw xpath-filter?               yang:xpath1.0
   +-rw subscription-config
   |  +-rw datastore-push-subscription*   [subscription-id]
   |  +--rw datastore-push-subscription*  [subscription-id]
   |     +--rw subscription-id            subscription-id
   |     +--rw target-datastore?          datastore
   |     +--rw stream?                    system-stream
   |     +--rw encoding?                  encoding
   |     +--rw start-time?                yang:date-and-time
   |     +--rw stop-time?                 yang:date-and-time
   |     +--rw (update-trigger)?
   |     |  +--:(periodic)
   |     |  |  +--rw period?              yang:timeticks
   |     |  +--:(on-change)
   |     |     +--rw no-synch-on-start?   empty
   |     |     +--rw dampening-period     yang:timeticks
   |     |     +--rw excluded-change*     change-type
   |     +--rw (filterspec)?
   |     |  +--:(inline)
   |     |  |  +--rw subtree-filter?      subtree-filter
   |     |  |  +--rw xpath-filter?        yang:xpath1.0
   |     |  +--:(by-reference)
   |     |     +--rw filter-ref?          filter-ref
   |     +--rw receiver-address
   |     |  +-rw (push-base-transport)?
   |     |     +-:(tcpudp)
   |     |        +-rw tcpudp
   |     |           +-rw address?        inet:host
   |     |           +-rw port?           inet:port-number
   |     +--rw subscription-priority?     uint8
   |     +--rw subscription-dependency?   string
   +-ro subscriptions
      +--ro datastore-push-subscription* [subscription-id]
         +--ro subscription-id            subscription-id
         +--ro configured-subscription?   empty
         +--ro subscription-status?       identityref
         +--ro target-datastore?          datastore
         +--ro stream?                    system-stream
         +--ro encoding?                  encoding
         +--ro start-time?                yang:date-and-time
         +--ro stop-time?                 yang:date-and-time
         +--ro (update-trigger)?
         |  +--:(periodic)
         |  |  +--ro period?              yang:timeticks
         |  +--:(on-change)
         |     +--ro no-synch-on-start?   empty
         |     +--ro dampening-period     yang:timeticks
         |     +--ro excluded-change*     change-type
         +--ro (filterspec)?
         |  +--:(inline)
         |  |  +--ro subtree-filter?      subtree-filter
         |  |  +--ro xpath-filter?        yang:xpath1.0
         |  +--:(by-reference)
         |     +--ro filter-ref?          filter-ref
         +--ro receiver-address
         |  +--ro (push-base-transport)?
         |     +--:(tcpudp)
         |        +--ro tcpudp
         |           +--ro address?       inet:host
         |           +--ro port?          inet:port-number
         +--rw subscription-priority?     uint8
         +--rw subscription-dependency?   string]]></artwork>
        </figure>

        <t/>
      </section>
    </section>

    <section title="YANG Module">
      <figure>
        <artwork><![CDATA[
namespace "urn:ietf:params:xml:ns:yang:ietf-restconf-push";

  prefix "rc-push";

  import ietf-datastore-push {        
    prefix ds-push;    
  }

  organization
   "IETF NETCONF (Network Configuration) Working Group";
    
  contact
   "WG Web:     <http://tools.ietf.org/wg/netconf/>
    WG List:    <mailto:netconf@ietf.org>

    WG Chair:   Mahesh Jethanandani
                <mailto:mjethanandani@gmail.com >

    WG Chair:   Mehmet Ersue
                <mailto:mehmet.ersue@nokia.com>

    Editor:   Eric Voit
              <mailto:evoit@cisco.com>

    Editor:   Alexander Clemm
              <mailto:alex@cisco.com>
        
    Editor:   Ambika Prasad Tripathy
              <mailto:ambtripa@cisco.com>

    Editor:   Einar Nilsen-Nygaard
              <mailto:einarnn@cisco.com>

    Editor:   Alberto Gonzalez Prieto
              <mailto:albertgo@cisco.com>";

  description
   "This module contains conceptual YANG specifications for
    Restconf datastore push.";

  revision 2015-10-01 {
    description
      "Initial revision.";
    reference "restconf YANG Datastore push";
  }

  grouping subscription-qos {
    description
     "This grouping describes Quality of Service information
      concerning a subscription.  This information is passed to lower
      layers for transport priortization and treatment";
    leaf subscription-priority {
      type uint8;
      description
       "Relative priority for a subscription.   Allows an underlying
        transport layer perform informed load balance allocations
        between various subscriptions";
    }
    leaf subscription-dependency {
      type string;
      description
       "Provides the Subscription ID of a parent subscription
        without which this subscription should not exist. In
        other words, there is no reason to stream these objects
        if another subscription is missing.";        
    }
  }  
  
  augment "/ds-push:subscription-config/" +
           "ds-push:datastore-push-subscription" {
    description 
      "Aguments configured subscriptions with QoS parameters."; 
    uses subscription-qos;
  }
  
  augment "/ds-push:subscriptions/" +
           "ds-push:datastore-push-subscription" {
    description 
      "Aguments the list of currently active subscriptions
        with QoS parameters.";
    uses subscription-qos;
  }

  augment "/ds-push:create-subscription/" +
           "ds-push:input" {
    description
      "Aguments the create subscription rpc with QoS parameters.";
    uses subscription-qos;
  }

  augment "/ds-push:modify-subscription/" +
           "ds-push:input" {
    description
      "Aguments the modify subscription rpc with QoS parameters.";
    uses subscription-qos;
  }

}
]]></artwork>
      </figure>
    </section>

    <section title="Security Considerations">
      <t>Subscriptions could be used to intentionally or accidentally overload
      resources of a Publisher. For this reason, it is important that the
      Publisher has the ability to prioritize the establishment and push of
      updates where there might be resource exhaust potential. In addition, a
      server needs to be able to suspend existing subscriptions when needed.
      When this occurs, the subscription status must be updated accordingly
      and the clients are notified.</t>

      <t>A Subscription could be used to retrieve data in subtrees that a
      client has not authorized access to. Therefore it is important that data
      pushed via a Subscription is authorized equivalently with regular data
      retrieval operations. Data being pushed to a client needs therefore to
      be filtered accordingly, just like if the data were being retrieved
      on-demand. The Netconf Authorization Control Model <xref
      target="RFC6536"/> applies.</t>

      <t>One or more Publishers could be used to overwhelm a Receiver which
      doesn&rsquo;t even support subscriptions. Therefore Updates MUST only be
      transmittable over Encrypted transports. Clients which do not want
      pushed data need only terminate or refuse any transport sessions from
      the Publisher.</t>

      <t>One or more Publishers could overwhelm a Receiver which is unable to
      control or handle the volume of Updates received. In deployments where
      this might be a concern, transports supporting per-subscription Flow
      Control and Prioritization (such as HTTP/2) should be selected.</t>

      <t>Another benefit is that a well-behaved Publisher implementation is
      that it is difficult to a Publisher to perform a DoS attack on a
      Receiver. DoS attack protection comes from:</t>

      <t><list style="symbols">
          <t>the requirement for trust of a TLS session before
          publication,</t>

          <t>the need for an HTTP transport augmentation on the Receiver,
          and</t>

          <t>that the Publication process is suspended when the Receiver
          doesn&rsquo;t respond.</t>
        </list></t>
    </section>
  </middle>

  <back>
    <references title="Normative References">
      <?rfc include="reference.RFC.2119"?>

      <?rfc include="reference.RFC.6520"?>

      <?rfc include="reference.RFC.6536"?>

      <?rfc include="reference.RFC.7540"?>

      <?rfc ?>
    </references>

    <references title="Informative References">
      <reference anchor="netconf-yang-push"
                 target="https://datatracker.ietf.org/doc/draft-clemm-netconf-yang-push/">
        <front>
          <title>Subscribing to YANG datastore push updates</title>

          <author fullname="A Clemm" initials="Alexander" surname="Clemm">
            <organization>Cisco</organization>
          </author>

          <author fullname="A Gonzalez Prieto" initials="Alberto"
                  surname="Gonzalez Prieto">
            <organization>Cisco</organization>

            <address>
              <postal>
                <street/>

                <city/>

                <region/>

                <code/>

                <country/>
              </postal>

              <phone/>

              <facsimile/>

              <email/>

              <uri/>
            </address>
          </author>

          <author fullname="E Voit" initials="Eric" surname="Voit">
            <organization>Cisco</organization>

            <address>
              <postal>
                <street/>

                <city/>

                <region/>

                <code/>

                <country/>
              </postal>

              <phone/>

              <facsimile/>

              <email/>

              <uri/>
            </address>
          </author>

          <date day="9" month="October" year="2015"/>
        </front>
      </reference>

      <reference anchor="pub-sub-reqs"
                 target="https://datatracker.ietf.org/doc/draft-ietf-i2rs-pub-sub-requirements/">
        <front>
          <title>Subscribing to datastore push updates</title>

          <author fullname="E Voit" initials="Eric " surname="Voit">
            <organization>Cisco</organization>

            <address>
              <postal>
                <street/>

                <city/>

                <region/>

                <code/>

                <country/>
              </postal>

              <phone/>

              <facsimile/>

              <email/>

              <uri/>
            </address>
          </author>

          <author fullname="Alexander Clemm" initials="Alexander"
                  surname="Clemm">
            <organization>Cisco</organization>
          </author>

          <author fullname="A Gonzalez Prieto" initials="Alberto"
                  surname="Gonzalez Prieto">
            <organization>Cisco</organization>

            <address>
              <postal>
                <street/>

                <city/>

                <region/>

                <code/>

                <country/>
              </postal>

              <phone/>

              <facsimile/>

              <email/>

              <uri/>
            </address>
          </author>

          <date day="2" month="October" year="2015"/>
        </front>
      </reference>

      <reference anchor="restconf"
                 target="https://datatracker.ietf.org/doc/draft-ietf-netconf-restconf/">
        <front>
          <title>RESTCONF Protocol</title>

          <author fullname="A Bierman" initials="Andy" surname="Bierman"/>

          <author fullname="M Bjorklund" initials="Martin" surname="Bjorklund"/>

          <author fullname="K Watsen" initials="Kent" surname="Watsen"/>

          <date day="6" month="July" year="2015"/>
        </front>
      </reference>

      <reference anchor="yang-json"
                 target="https://datatracker.ietf.org/doc/draft-ietf-netmod-yang-json/">
        <front>
          <title>JSON Encoding of Data Modeled with YANG</title>

          <author fullname="L. Lhotka" initials="Ladislav" surname="Lhotka">
            <organization/>
          </author>

          <date day="7" month="October" year="2015"/>
        </front>
      </reference>

      <reference anchor="W3C-20121211"
                 target="http://www.w3.org/TR/2012/CR-eventsource-20121211">
        <front>
          <title>Server-Sent Events, World Wide Web Consortium CR
          CR-eventsource-20121211</title>

          <author fullname="I Hickson">
            <organization/>
          </author>

          <date month="December" year="2012"/>
        </front>
      </reference>

      <reference anchor="call-home"
                 target="https://tools.ietf.org/html/draft-ietf-netconf-call-home-09">
        <front>
          <title>NETCONF Call Home and RESTCONF Call Home</title>

          <author fullname="K Watsen" initials="K" surname="Watsen">
            <organization/>
          </author>

          <date day="21" month="July" year="2015"/>
        </front>
      </reference>
    </references>

    <section anchor="app.ex-if"
             title="Dynamic YANG Subscription when the Subscriber and Receiver are different">
      <t>The methods of Sections 3.3.1 and 3.3.2 can be combined to enable
      deployment models where the Subscriber and Receiver are different. Such
      separation can be useful with some combination of:</t>

      <t><list style="symbols">
          <t>An operator wants any Subscriptions immediately deleted should
          TLS connectivity be lost. (I.e., Subscriptions don&rsquo;t default
          into a &lsquo;Suspended&rsquo; state on the Publisher.)</t>

          <t>An operator wants the Publisher to include highly restrictive
          capacity management and security mechanisms outside of domain of
          existing operational or programmatic interfaces.</t>

          <t>Restconf is not desired on the Receiver.</t>

          <t>The Publisher doesn&rsquo;t want to maintain Restconf
          subscriptions with many Receivers.</t>
        </list>To do this, first the necessary information must be signaled as
      part of the &lt;create-subscription&gt;. This includes all the
      information described in section 3.3.2, with the exception of the
      security credentials. (It is assumed that any security credentials
      required for establishing any transport connections are pre-provisioned
      on all devices.)</t>

      <t>Using this set of Subscriber provided information, the same process
      described within section 3.3.2 will be followed. There is one exception.
      When an HTTP status code is 201 is received by the Publisher, it will
      inform the Subscriber of Subscription establishment success via its
      Restconf connection.</t>

      <t>After successful establishment, if the Subscriber wishes to maintain
      the state of Receiver subscriptions, it can simply place a separate
      on-change Subscription into the &ldquo;Subscriptions&rdquo; subtree of
      the YANG Datastore on the Publisher.</t>

      <t>Putting it all together, the message flow is:</t>

      <figure>
        <artwork><![CDATA[  +------------+          +-----------+            +----------+
  | Subscriber |          | Publisher |            | Receiver |
  +------------+          +-----------+            +----------+
        | Restconf PUT:        |                            |
        | <create-subscription>|                            |
        |--------------------->|                            | 
        |                      |                            |
        |                      |<-----------TLS------------>| 
        |                      |                            |
        |                      |HTTP POST (Sub ID, data1,   |
        |                      |(stream ID, URI?))          | 
        |                      |--------------------------->|
        |                      |          HTTP 201 (Created)|
        |                      |<---------------------------| 
        |     Success: HTTP 204|                            |
        |<---------------------|                            |
        |                      |HTTP POST (Sub ID, data2)   | 
        |                      |--------------------------->| 
        |                      |  HTTP 200 or 202 (Accepted)| 
        |                      |<---------------------------| 
        |                      |            data3           | 
        |                      |<-------------------------->| 
        |                      |                            |
]]></artwork>
      </figure>

      <t/>
    </section>

    <section title="End-to-End Deployment Guidance">
      <t>Several technologies are expected to be seen within a deployment to
      achieve security and ease-of-use requirements. These are not necessary
      for an implementation of this specification, but will be useful to
      consider when considering the operational context.</t>

      <t/>

      <section title="Call Home">
        <t>Pub/Sub implementations should have the ability to transparently
        incorporate lower layer technologies such as Call Home so that secure
        TLS connections are always originated from the Publisher. There is a
        Restconf Call home function in <xref target="call-home"/>. For
        security reasons, this should be implemented as desired.</t>

        <t/>
      </section>

      <section title="TLS Heartbeat">
        <t>Unlike NETCONF, HTTP sessions might not quickly allow a Subscriber
        to recognize when the communication path has been lost from the
        Publisher. To recognize this, it is possible for a Receiver (usually
        the subscriber) to establish a TLS heartbeat <xref target="RFC6520"/>.
        In the case where a TLS heartbeat is included, it should be sent just
        from Receiver to Publisher. Loss of the heartbeat should result in the
        Subscription being terminated with the Subscriber (even when the
        Subscriber and Receiver are different). The Subscriber can then
        attempt to re-establish the subscription if desired. If the
        Subscription remains active on the Publisher, future receipt of
        objects associated with that (or any other unknown) subscription ID
        should result in a &lt;delete-subscription&gt; being returned to the
        Publisher from the Receiver.</t>

        <t/>
      </section>

      <section title="Putting it together">
        <t>If Subscriber and receiver are same entity then subscriber can
        direct send create_subscription message to publisher. Once the
        subscription moved to accepted state, the receiver can use Server Sent
        Events <xref target="W3C-20121211"/> transport strategy to subscriber
        event notifications for the data as defined in<xref
        target="restconf"/>.</t>
      </section>
    </section>
  </back>
</rfc>
