Internet-Draft | COREPUBSUB | March 2023 |
Koster, et al. | Expires 14 September 2023 | [Page] |
This document describes a publish-subscribe architecture for CoAP that extends the capabilities of CoAP for supporting nodes with long breaks in connectivity and/or up-time. The Constrained Application Protocol (CoAP) is used by CoAP clients both to publish and to subscribe via a known topic resource.¶
This note is to be removed before publishing as an RFC.¶
Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-core-coap-pubsub/.¶
Discussion of this document takes place on the core Working Group mailing list (mailto:core@ietf.org), which is archived at https://mailarchive.ietf.org/arch/browse/core/. Subscribe at https://www.ietf.org/mailman/listinfo/core/.¶
Source for this draft and an issue tracker can be found at https://github.com/core-wg/coap-pubsub.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 14 September 2023.¶
Copyright (c) 2023 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
The Constrained Application Protocol (CoAP) [RFC7252] supports machine-to-machine communication across networks of constrained devices and constrained networks. CoAP uses a request/response model where clients make requests to servers in order to request actions on resources. Depending on the situation the same device may act either as a server, a client, or both.¶
One important class of constrained devices includes devices that are intended to run for years from a small battery, or by scavenging energy from their environment. These devices have limited reachability because they spend most of their time in a sleeping state with no network connectivity. Another important class of nodes are devices with limited reachability due to middle-boxes like Network Address Translators (NATs) and firewalls.¶
For these nodes, the client/server-oriented architecture of REST can be challenging when interactions are not initiated by the devices themselves. A publish/subscribe-oriented architecture where nodes are separated by a broker and data is exchanged via topics might fit these nodes better.¶
This document applies the idea of publish-subscribe to Constrained RESTful Environments. It introduces a broker that allows to create, discover subscribe and publish on topics. The broker enables store-and-forward data exchange between CoAP endpoints, thereby facilitating the communication of nodes with limited reachability, providing simple many-to-many communication, and easing integration with other publish/subscribe systems.¶
This specification requires readers to be familiar with all the terms and concepts that are discussed in [RFC8288] and [RFC6690]. Readers should also be familiar with the terms and concepts discussed in [RFC7252] and [RFC9167]. The URI template format [RFC6570] is used to describe the REST API defined in this specification.¶
This specification makes use of the following terminology:¶
A messaging paradigm in which messages are published to a broker, and potential receivers can subscribe to a broker to receive messages. Message producers do not need to know where the message will be eventually sent. The broker matches publications and subscriptions, and delivers publications to subscribed receivers.¶
CoAP clients can act as publishers or as subscribers. Publishers propose topics for creation and send CoAP messages (publications) to the broker on specific topics. Subscribers have an ongoing observation relation (subscription) to a topic. Publishers and subscribers do not need to have any knowledge of each other, but they must know the topic they are publishing and subscribing to.¶
A resource collection is a group of related resources that share a common base URI. In this case the the topic collection contains resources of the type "topic resource". CoAP clients can discover and interact with the resources in a collection by sending CoAP requests to the URI of the collection.¶
An entry within a topic collection in a broker. Topics are created and configured before any data can be published. CoAP clients can propose new topics to be created, but it is up to the broker to decide whether and how a topic is created. The broker also decides the URI of each topic resource and of the topic-data resource when hosted at the broker. The creation, configuration, and discovery of topics at a broker are specified in Section 2. Interactions about the topic-data are defined in Section 2.7.¶
Topic resources contain a property called "topic-data". The topic-data resource is a CoAP URI used by publishers and subscribers to publish (PUT) and subscribe (GET with Observe) to data (see Section 2).¶
A CoAP server that hosts one or more topic collections containing topic resources. The broker is responsible for the store-and-forward of state update representations when the topic-data URI points to a resource hosted on the broker. The broker is also responsible of handling the topic lifecycle as defined in Section 2.6.1. The creation, configuration, and discovery of topics at a broker is specified in Section 2.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
Figure 1 shows a simple Publish/Subscribe architecture over CoAP. In it, publishers submit their data over a RESTful interface to a broker-managed resource (topic) and subscribers observe this resource using [RFC7641]. Resource state information is updated between the CoAP clients and the broker via topics. Topics are created by the broker but the initial configuration can be proposed by a client, normally a publisher.¶
The broker is responsible for the store-and-forward of state update representations between CoAP clients. Subscribers observing a resource will receive notifications, the delivery of which is done on a best-effort basis.¶
This document describes two sets of interactions, interactions to configure topics and their lifecycle (see Section 2.5) and interactions about the topic data (see Section 2.7).¶
Topic resource interactions are discovery, create, read configuration, update configuration, delete configuration and handle the management of the topics.¶
Topic data interactions are publish, subscribe, unsubscribe, read and are oriented on how data is transferred from a publisher to a subscriber.¶
Figure 2 shows the resources of a Topic Collection that can be managed at the Broker.¶
The Broker exports a topic-collection resource, with resource type "core.ps.coll" defined in Section 5 of this document. The interfaces for the topic-collection resource is defined in Section 2.4.¶
The configuration side of a "publish/subscribe broker" consists of a collection of topics. These topics as well as the collection itself are exposed by a CoAP server as resources (see Figure 3). Each topic has a topic and a topic data resources. The topic resource is used by a client creating or administering a topic. The topic data resource is used by the publishers and the subscribers to a topic.¶
Each topic resource is represented as a link, where the link target is the URI of the topic resource.¶
Each topic-data is represented as a link, where the link target is the URI of the topic-data resource. A topic-data link is an entry within the topic resource called 'topic_data' (see Section 2.2.1).¶
The list can be represented as a Link Format document [RFC6690]. The link to each topic resource specifies the link target attribute 'rt' (Resource Type), with value "core.pubsub.conf" defined in this document.¶
A CoAP client can create a new topic by submitting an initial configuration for the topic (see Section 2.4.3). It can also read and update the configuration of existing topics and delete them when they are no longer needed (see Section 2.5).¶
The configuration of a topic itself consists of a set of properties that can be set by a client or by the broker.¶
The CBOR map includes the following configuration parameters, whose CBOR abbreviations are defined in Section 3 of this document.¶
A topic is represented as a CBOR map containing the configuration properties of the topic as top-level elements.¶
Unless specified otherwise, these are defined in this document and their CBOR abbreviations are defined in Section 3.¶
Below are the defined default values for the topic parameters:¶
Discovery involves that of the Broker, topic collections, topic resources and topic data.¶
CoAP clients MAY discover brokers by using CoAP Simple Discovery, via multicast, through a Resource Directory (RD) [RFC9167] or by other means specified in extensions to [RFC7252]. Brokers MAY register with a RD by following the steps on Section 5 of [RFC9167] with the resource type set to "core.ps" as defined in Section 5 of this document.¶
Brokers SHOULD expose a link to the entry point of the pubsub API at their .well-known/core location [RFC6690]. The specific resource path is left for implementations, examples in this document may use the "/ps" path.¶
Example:¶
=> GET Uri-Path: ./well-known/core Resource-Type: core.ps <= 2.05 Content </ps>;rt=core.ps;ct=40¶
A Broker can offer a topic discovery entry point to enable clients to find topics of interest. The resource entry point thus represents a collection of related resources as specified in [RFC6690] and is identified by the resource type "core.ps.coll".¶
The interactions with topic collections are further defined in Section 2.4.¶
A topic collection is a group of topic resources that define the properties of the topics themselves (see Section Section 2.2.2). Each topic resource is represented as a link to its corresponding resource URI. The list can be represented as a Link Format document [RFC6690]. Topic resources are identified by the resource type "core.ps.conf".¶
Within each topic resource there is a set of configuration properties (see Section Section 2.2.1). The 'topic_data' property contains the URI of the topic data resource that a CoAP client can subscribe to. Resources exposing resources of the topic data type are expected to use the resource type 'core.ps.data'.¶
These are the interactions that can happen at the topic collection level.¶
A client can request a collection of the topics present in the broker by making a GET request to the collection URI.¶
On success, the server returns a 2.05 (Content) response with a representation of the list of all topic resources (see Section Section 2.2.2) in the collection.¶
Depending on the permission set each client MAY receive a different list of topics that they are authorized to read.¶
Example:¶
=> 0.01 GET Uri-Path: ps Uri-Path: tc <= 2.05 Content Content-Format: 40 (application/link-format) </ps/tc/temperature>;rt="core.ps.conf", </ps/tc/humidity>;rt="core.ps.conf"¶
A client can filter a collection of topics by submitting the representation of a topic filter (see Section Section 2.5.2) in a FETCH request to the topic collection URI.¶
On success, the server returns a 2.05 (Content) response with a representation of a list of topics in the collection (see Section Section 2.3.2) that match the filter in CoRE link format [RFC6690].¶
Example:¶
=> 0.05 FETCH Uri-Path: ps Uri-Path: tc Content-Format: TBD (application/pubsub+cbor) { "resource_type" : "core.ps.conf", "target_attribute" : "temperature" } <= 2.05 Content Content-Format: 40 (application/link-format) </living_room_sensor>;anchor="coap://[2001:db8::2]/ps/tc/h9392", </kitchen_sensor>;anchor="coap://[2001:db8::2]/ps/tc/f3192"¶
A client can add a new topic to a collection of topics by submitting a representation of the initial topic resource (see Section Section 2.2.2) in a POST request to the topic collection URI.¶
On success, the server returns a 2.01 (Created) response indicating the topic URI of the new topic and the current representation of the topic resource.¶
If a topic manager is present in the broker, the topic creation may require manager approval subject to certain conditions. If the conditions are not fulfilled, the manager MUST respond with a 4.03 (Forbidden) error. The response MUST have Content-Format set to "application/core-pubsub+cbor".¶
The broker MUST respond with a 4.00 (Bad Request) error if any received parameter is specified multiple times, invalid or not recognized.¶
A CoAP endpoint creating a topic may specify a 'topic_data' URI different than that used by the broker. The broker may then simply forward the observation requests to the 'topic_data' URI.¶
If the 'topic_data' is empty the broker will assign a resource for a publisher to publish to.¶
=> 0.02 POST Uri-Path: ps Uri-Path: tc Content-Format: TBD2 (application/core-pubsub+cbor) TBD (this should be a CBOR map with the mandatory parameters) { "topic_name" : "living_room_sensor" "resource_type" : "core.ps.conf" } <= 2.01 Created Location-Path: ps/h9392 Content-Format: TBD2 (application/core-pubsub+cbor) TBD (this should be a CBOR map) { "topic_name" : "living_room_sensor", "topic_data" : "coap://[2001:db8::2]/ps/data/6578616d706c65" "resource_type" : "core.ps.conf" }¶
These are the interactions that can happen at the topic resource level.¶
A client can read the configuration of a topic by making a GET request to the topic resource URI.¶
On success, the server returns a 2.05 (Content) response with a representation of the topic resource. The response has as payload the representation of the topic resource as specified in Section 2.2.2.¶
If a topic manager (TBD) is present in the broker, retrieving topic information may require manager approval subject to certain conditions (TBD). If the conditions are not fulfilled, the manager MUST respond with a 4.03 (Forbidden) error. The response MUST have Content-Format set to "application/core-pubsub+cbor".¶
The response payload is a CBOR map, whose possible entries are specified in Section 2.2.2 and use the same abbreviations defined in Section 3.¶
Example:¶
=> 0.01 GET Uri-Path: ps Uri-Path: tc Uri-Path: h9392 <= 2.05 Content Content-Format: TBD2 (application/core-pubsub+cbor) { "topic_name" : "living_room_sensor", "topic_data" : "coap://[2001:db8::2]/ps/data/6578616d706c65", "resource_type": "core.ps.conf", "media_type": "application/senml-cbor", "target_attribute": "temperature", "expiration_date": "", "max_subscribers": -1 }¶
A client can read the configuration of a topic by making a FETCH request to the topic resource URI with a filter for specific parameters. This is done in order to retrieve part of the current topic resource.¶
The request contains a CBOR map with a configuration filter or 'conf_filter', a CBOR array with CBOR abbreviation. Each element of the array specifies one requested configuration parameter of the current topic resource (see Section 2.2.2).¶
On success, the server returns a 2.05 (Content) response with a representation of the topic resource. The response has as payload the partial representation of the topic resource as specified in Section 2.2.2.¶
If a topic manager (TBD) is present in the broker, retrieving topic information may require manager approval subject to certain conditions (TBD). If the conditions are not fulfilled, the manager MUST respond with a 4.03 (Forbidden) error.¶
The response payload is a CBOR map, whose possible entries are specified in Section 2.2.2 and use the same abbreviations defined in Section 3.¶
Both request and response MUST have Content-Format set to "application/core-pubsub+cbor".¶
Example:¶
=> 0.05 FETCH Uri-Path: ps Uri-Path: tc Uri-Path: h9392 Content-Format: TBD2 (application/core-pubsub+cbor) { "conf_filter" : [topic_data, media_type] } <= 2.05 Content Content-Format: TBD2 (application/core-pubsub+cbor) { "topic_data" : "coap://[2001:db8::2]/ps/data/6578616d706c65", "media_type": "application/senml-cbor" }¶
A client can update the configuration of a topic by submitting the representation of the updated topic (see Section 3.1.3) in a PUT or POST request to the topic URI. Any existing properties in the configuration are overwritten by this update.¶
On success, the server returns a 2.04 (Changed) response and the current full resource representation. The broker may chose not to overwrite parameters that are not explicitly modified in the request.¶
Example:¶
=> 0.03 PUT Uri-Path: ps Uri-Path: tc Uri-Path: h9392 Content-Format: TBD2 (application/core-pubsub+cbor) { "topic_name" : "living_room_sensor", "topic_data" : "coap://[2001:db8::2]/ps/data/6578616d706c65", "target_attribute": "temperature", "expiration_date": "2023-04-28T23:59:59Z", "max_subscribers": 2 } <= 2.04 Changed Content-Format: TBD2 (application/core-pubsub+cbor) TBD (this should be a CBOR map) { "topic_name" : "living_room_sensor", "topic_data" : "coap://[2001:db8::2]/ps/data/6578616d706c65", "resource_type": "core.ps.conf", "media_type": "application/senml-cbor", "target_attribute": "temperature", "expiration_date": "2023-04-28T23:59:59Z", "max_subscribers": 2 }¶
A client can delete a topic by making a CoAP DELETE request on the topic resource URI.¶
On success, the server returns a 2.02 (Deleted) response.¶
When a topic resource is deleted, the broker SHOULD also delete the topic data resource, unsubscribe all subscribers by removing them from the list of observers and returning a final 4.04 (Not Found) response as per [RFC7641] Section 3.2. Example:¶
=> 0.04 DELETE Uri-Path: ps Uri-Path: tc Uri-Path: h9392 <= 2.02 Deleted¶
Unless a topic is configured to use a different mechanism, publish/ subscribe is performed as follows: A publisher publishes to a topic by submitting the data in a PUT request to a broker-managed "topic data resource". This causes a change to the state of that resources. Any subscriber observing the resource [RFC7641] at that time receives a notification about the change to the resource state. Observations are maintained and terminated as specified in [RFC7641].¶
As shown in Section 2, each topic contains two resources: topic resource and topic data. In that section we explained the creation and configuration of the topic resources. This section will explain the management of topic data resources.¶
A topic data resource does not exist until some initial data has been published to it. Before initial data has been published, the topic data resource yields a 4.04 (Not Found) response. If such a "half created" topic is undesired, the creator of the topic can simply immediately publish some initial placeholder data to make the topic "fully created".¶
URIs for topic resources are broker-generated. URIs for topic-data MAY also be broker-generated or client-generated. There does not need to be any URI pattern dependence between the URI where the data exists and the URI of the topic resource. Topic resource and data resources might even be hosted on different servers.¶
When a topic is newly created, it is first placed by the server into the HALF CREATED state (see Figure 4). In this state, a client can read and update the configuration of the topic and delete the topic. A publisher can publish to the topic data resource. However, a subscriber cannot yet observe the topic data resource nor read the latest data.¶
After a publisher publishes to the topic for the first time, the topic is placed into the FULLY CREATED state. In this state, a client can read, update and delete the topic; a publisher can publish to the topic data resource; and a subscriber can observe the topic data resource.¶
When a client deletes a topic resource, the topic is placed into the DELETED state and shortly after removed from the server. In this state, all subscribers are removed from the list of observers of the topic data resource and no further interactions with the topic are possible.¶
When a client deletes a topic data, the topic is placed into the HALF CREATED state, where clients can read, update and delete the topic and awaits for a publisher to begin publication.¶
The server hosting a data resource may have to handle a potentially very large number of publishers and subscribers at the same time. This means the server can easily become overwhelmed if it receives too many publications in a short period of time.¶
In this situation, if a client is sending publications too fast, the server SHOULD return a 4.29 (Too Many Requests) response [RFC8516]. As described in [RFC8516], the Max-Age option [RFC7252] in this response indicates the number of seconds after which the client may retry. The Broker MAY stop publishing messages from the client for the indicated time.¶
When a client receives a 4.29 (Too Many Requests) response, it MUST NOT send any new publication requests to the same topic data resource before the time indicated by the Max-Age option has passed.¶
TBD: intro and image that shows a topic data URI hosted in a different endpoint than the broker¶
A topic must have been created in order to publish data to it (See Section Section 2.4.3) and be in the half-created state in order to the publish operation to work (see Section 2.6.1).¶
A client can publish data to a topic by submitting the data in a PUT request to the 'topic_data' URI as indicated in its topic resource property. Please note that the 'topic_data' URI is not the same as the topic URI used for configuring the topic (see Section 2.2.2).¶
On success, the server returns a 2.04 (Updated) response. However, when data is published to the topic for the first time, the server instead MUST return a 2.01 (Created) response and set the topic in the fully-created state (see Section 2.6.1).¶
If the request does not have an acceptable content format, the server returns a 4.15 (Unsupported Content Format) response.¶
If the client is sending publications too fast, the server returns a 4.29 (Too Many Requests) response [RFC8516].¶
Example of first publication:¶
=> 0.03 PUT Uri-Path: ps Uri-Path: data Uri-Path: 6578616d706c65 Content-Format: 110 { "n": "temperature", "u": "Cel", "t": 1621452122, "v": 23.5 } <= 2.01 Created¶
Example of subsequent publication:¶
=> 0.03 PUT Uri-Path: ps Uri-Path: data Uri-Path: 6578616d706c65 Content-Format: 110 { "n": "temperature", "u": "Cel", "t": 182734122, "v": 22.5 } <= 2.04 Updated¶
A client can subscribe to a topic by sending a CoAP GET request with the Observe set to '0' to subscribe to resource updates. [RFC7641].¶
On success, the broker MUST return 2.05 (Content) notifications with the data.¶
If the topic is not yet in the fully created state (see Section 2.6.1) the broker SHOULD return a response code 4.04 (Not Found).¶
The following response codes are defined for the Subscribe operation:¶
2.05 "Content". Successful subscribe with observe response, current value included in the response.¶
4.04 "Not Found". Topic does not exist.¶
TBD: Do we want to treat max_clients as an error?¶
If the 'max_clients' parameter has been reached, the server must treat that as specified in section 4.1 of [RFC7641]. The response MUST NOT include an Observe Option, the absence of which signals to the subscriber that the subscription failed.¶
Example:¶
=> 0.01 GET Uri-Path: ps Uri-Path: data Uri-Path: 6578616d706c65 Observe: 0 <= 2.05 Content Content-Format: 110 Observe: 10001 Max-Age: 15 [...SenML data...] <= 2.05 Content Content-Format: 110 Observe: 10002 Max-Age: 15 [...SenML data...] <= 2.05 Content Content-Format: 110 Observe: 10003 Max-Age: 15 [...SenML data...]¶
A CoAP client can unsubscribe simply by cancelling the observation as described in Section 3.6 of [RFC7641]. The client MUST either use CoAP GET with the Observe Option set to 1 or send a CoAP Reset message in response to a notification.¶
A publisher MAY delete a topic by making a CoAP DELETE request on the 'topic_data' URI.¶
On success, the server returns a 2.02 (Deleted) response.¶
When a topic_data resource is deleted, the broker SHOULD also delete the 'topic_data' parameter in the topic resource, unsubscribe all subscribers by removing them from the list of observers and return a final 4.04 (Not Found) response as per [RFC7641] Section 3.2. The topic is then set back to the half created state as per Section 2.6.1.¶
Example:¶
=> 0.04 DELETE Uri-Path: ps Uri-Path: data Uri-Path: 6578616d706c65 <= 2.02 Deleted¶
A client can get the latest published topic data by making a GET request to the 'topic_data' URI in the broker. Please note that discovery of the 'topic_data' parameter is a required previous step (see Section 2.5.1).¶
On success, the server MUST return 2.05 (Content) response with the data.¶
If the target URI does not match an existing resource or the topic is not in the fully created state (see Section 2.6.1), the broker SHOULD return a response code 4.04 (Not Found).¶
If the broker can not return the requested content format it MUST return a response code 4.15 (Unsupported Content Format).¶
Example:¶
=> 0.01 GET Uri-Path: ps Uri-Path: data Uri-Path: 6578616d706c65 <= 2.05 Content Content-Format: 110 Max-Age: 15 { "n": "temperature", "u": "Cel", "t": 1621452122, "v": 23.5 }¶
This document defines parameters used in the messages exchanged between a client and the broker during the topic creation and configuration process (see Section 2.2.2). The table below summarizes them and specifies the CBOR key to use instead of the full descriptive name.¶
Note that the media type application/core-pubsub+cbor MUST be used when these parameters are transported in the respective message fields.¶
TBD.¶
This document registers one attribute value in the Resource Type (rt=) registry established with [RFC6690] and appends to the definition of one CoAP Response Code in the CoRE Parameters Registry.¶
The current version of this document contains a substantial contribution by Klaus Hartke's proposal [I-D.hartke-t2trg-coral-pubsub], which defines the topic resource model and structure as well as the topic lifecycle and interactions. It also follows a similar architectural design as that provided by Marco Tiloca's [I-D.ietf-ace-oscore-gm-admin].¶
The authors would like to also thank Carsten Bormann, Hannes Tschofenig, Zach Shelby, Mohit Sethi, Peter van der Stok, Tim Kellogg, Anders Eriksson, Goran Selander, Mikko Majanen, and Olaf Bergmann for their valuable contributions and reviews.¶