split long sections for owner use cases

git-svn-id: file:///home/ksmith/gitmigration/svn/xmpp/trunk@1152 4b5297f7-1745-476d-ba37-a9c6900126ab
This commit is contained in:
Peter Saint-Andre 2007-08-15 15:24:38 +00:00
parent 9d6de8052a
commit e991543a67
1 changed files with 433 additions and 288 deletions

View File

@ -276,8 +276,8 @@
<section1 topic='Introduction' anchor='intro'>
<section2 topic='Overview' anchor='intro-overview'>
<p>As Jabber/XMPP technologies have matured, the need for a generic publish-subscribe ("pubsub") mechanism has arisen in a number of domains. These include (but are not limited to): news feeds and content syndication, extended presence, avatar management, shared bookmarks, auction and trading systems, online catalogs, workflow systems, network management systems, NNTP gateways, profile management, and event notification.</p>
<p>In all of these domains, it is desirable for data communication to follow the classic "publish-subscribe" or "observer" design pattern: a person or application publishes information, and an event notification or the data itself is broadcasted to all authorized subscribers. In general, the relationship between the publisher and subscriber is mediated by a service that receives publication requests, broadcasts event notifications and/or the data itself to subscribers, and enables privileged entities to manage lists of people or applications that are authorized to publish or subscribe. In most pubsub services, the focal point for publication and subscription is a "topic" or "node" to which publishers send data and from which subscribers receive notifications and/or data. Additionally, some nodes may also maintain a history of events and provide other services that supplement the pure pubsub model.</p>
<p>This document defines a single, cohesive, generic protocol, which all forms of pubsub can utilize. While compliant implementations are not required to implement all of the features defined herein, this document addresses most use cases that may be requested of a pubsub service. (For information about which features are required and which are recommended or optional, consult the <link url='#features'>Feature Summary</link>.) Other specifications may define "subsets" or "profiles" of publish-subscribe (e.g., &xep0163;) for use in specialized contexts, but such profiles are out of scope for this document.</p>
<p>In all of these domains, it is desirable for data communication to follow the classic "publish-subscribe" or "observer" design pattern: a person or application publishes information, and an event notification (without or without payload) is broadcasted to all authorized subscribers. In general, the relationship between the publisher and subscriber is mediated by a service that receives publication requests, broadcasts event notifications to subscribers, and enables privileged entities to manage lists of people or applications that are authorized to publish or subscribe. In most pubsub services, the focal point for publication and subscription is a "topic" or "node" to which publishers send data and from which subscribers receive notifications. Additionally, some nodes may also maintain a history of events and provide other services that supplement the pure pubsub model.</p>
<p>This document defines a single, cohesive, generic protocol that all forms of pubsub can use. While compliant implementations are not required to implement all of the features defined herein, this document addresses most use cases that may be requested of a pubsub service. (For information about which features are required and which are recommended or optional, consult the <link url='#features'>Feature Summary</link>.) Other specifications may define "subsets" or "profiles" of publish-subscribe for use in specialized contexts (e.g., &xep0163;), but such profiles are out of scope for this document.</p>
</section2>
<section2 topic='How It Works' anchor='intro-howitworks'>
<p>This specification is large. However, the basic idea behind pubsub is rather simple (see <link url='#publisher-publish'>Publish an Item to a Node</link>):</p>
@ -293,7 +293,7 @@
id='pub1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<publish node='princely_musings'>
<item id='ae890ac52d0df67ed7cfdf51b644e901'>
<item>
<entry xmlns='http://www.w3.org/2005/Atom'>
<title>Soliloquy</title>
<summary>
@ -347,7 +347,7 @@ And by opposing end them?
</event>
</message>
<message from='pubsub.shakespeare.lit' to='marcellus@denmark.lit' id='fez'>
<message from='pubsub.shakespeare.lit' to='bard@shakespeare.lit' id='fez'>
<event xmlns='http://jabber.org/protocol/pubsub#event'>
<items node='princely_musings'>
<item id='ae890ac52d0df67ed7cfdf51b644e901'>
@ -357,7 +357,7 @@ And by opposing end them?
</event>
</message>
]]></example>
<p>An even simpler example is that of a transient node that sends only notifications without a payload:</p>
<p>Here is an even simpler example: a transient node that sends only notifications without a payload:</p>
<example caption='A Transient Notification'><![CDATA[
<message from='pubsub.shakespeare.lit' to='francisco@denmark.lit'>
<event xmlns='http://jabber.org/protocol/pubsub#event'>
@ -413,7 +413,7 @@ And by opposing end them?
<!-- =================== MAYS and SHOULDS =================== -->
<p>Some of the possible uses of a Jabber-based pubsub service will require other features, but these features are OPTIONAL and therefore not mandatory for compliance with this specification. However, if these features are implemented, they MUST adhere to the protocol described herein in to be compliant. These features include:</p>
<ul>
<li>A service MAY cache the last item published to a node (even if the "persistent-items" option is not set to true); if it does so default "cache-last-item" to true, it SHOULD send the last published item (or notification thereof) to subscribed entities based on configuration of the "send_last_published_item" field.</li>
<li>A service MAY cache the last item published to a node (even if the "persistent-items" option is set to false); if it does default "cache-last-item" to true, it SHOULD send the last published item (or notification thereof) to subscribed entities based on configuration of the "send_last_published_item" field.</li>
<li>A node owner SHOULD be able to specify who may subscribe to a node.</li>
<li>A node owner SHOULD be able to specify who may publish to a node.</li>
<li>A node MAY be configured to deliver the published payload inside the event notification.</li>
@ -478,10 +478,10 @@ And by opposing end them?
</tr>
</table>
<p>* Note: A service MAY allow any publisher to delete any item once it has been published to that node instead of allowing only the original publisher to remove it (this is discoverable via the "pubsub#delete-any" feature).</p>
<p>The ways in which an entity changes its affiliation with a node are well-defined. Typically, an owner action is required to make an affiliation state transition. Affiliation changes and their triggering actions are specified in the following table.</p>
<p>The ways in which an entity changes its affiliation with a node are well-defined. Typically, action by an owner is required to make an affiliation state transition. Affiliation changes and their triggering actions are specified in the following table.</p>
<table caption='Affiliation State Chart'>
<tr>
<th>--&gt;</th>
<th>&#160;</th>
<th>Outcast</th>
<th>None</th>
<th>Publisher</th>
@ -539,7 +539,7 @@ And by opposing end them?
</tr>
<tr>
<td>Subscribed</td>
<td>An entity is subscribed to a node. The node MUST send all event notifications (and, if configured, payloads) to the entity while it is in this state.</td>
<td>An entity is subscribed to a node. The node MUST send all event notifications (and, if configured, payloads) to the entity while it is in this state (subject to subscriber configuration and content filtering).</td>
</tr>
</table>
</section2>
@ -550,7 +550,7 @@ And by opposing end them?
<p>A pubsub service MUST validate publish requests against the configuration of the node along both of these dimensions (see the <link url='#publisher-publish'>Publish An Item to a Node</link> section of this document for the relevant error conditions).</p>
<p>Whether an item must be provided by the publisher, and whether an item ID is provided by the publisher or generated by the pubsub service, depends on the type of event being published. We can summarize the relevant rules as follows:</p>
<table caption='Event Types, Items, and Item IDs'>
<tr><th>--&gt;</th><th>Notification</th><th>Payload</th></tr>
<tr><th>&#160;</th><th>Notification</th><th>Payload</th></tr>
<tr>
<td><strong>Persistent</strong></td>
<td>Publisher MUST include an &ITEM; element, which MAY be empty or contain a payload; if item ID is not provided by publisher, it MUST be generated by pubsub service</td>
@ -617,7 +617,7 @@ And by opposing end them?
<section2 topic='Addressing' anchor='addressing'>
<p>If a pubsub node is addressable, it MUST be addressable either (1) as a JID or (2) as the combination of a JID and a node. <note>These nodes are equivalent to those used in <cite>XEP-0030: Service Discovery</cite>.</note></p>
<section3 topic='JID' anchor='addressing-jid'>
<p>If a pubsub node is addressable as a JID, the NodeID MUST be the resource identifier, and MUST NOT be specified by the "user" portion (node identifier) of the JID (e.g. "domain.tld/NodeID" and "user@domain.tld/NodeID" are allowed; "NodeID@domain.tld" is not allowed). JID addressing SHOULD be used when interacting with a pubsub node using a protocol that does not support the node attribute. For example, when a service makes it possible for entities to subscribe to nodes via presence, it would address nodes as JIDs. If a pubsub node is addressable as a JID, the pubsub service MUST ensure that the NodeID conforms to the Resourceprep profile of Stringprep as described in <cite>RFC 3920</cite>.</p>
<p>If a pubsub node is addressable as a JID, the NodeID MUST be the resource identifier, and MUST NOT be specified by the "user" portion (node identifier) of the JID (e.g. "domain.tld/NodeID" and "user@domain.tld/NodeID" are allowed; "NodeID@domain.tld" is not allowed <note>This rule does not apply to the root collection node, if any.</note>). JID addressing SHOULD be used when interacting with a pubsub node using a protocol that does not support the node attribute. For example, when a service makes it possible for entities to subscribe to nodes via presence, it would address nodes as JIDs. If a pubsub node is addressable as a JID, the pubsub service MUST ensure that the NodeID conforms to the Resourceprep profile of Stringprep as described in <cite>RFC 3920</cite>.</p>
<p>Consider the following example, in which the pubsub service is located at the hostname pubsub.shakespeare.lit.</p>
<example caption='Node addressed as domain.tld/NodeID'><![CDATA[
<iq to='pubsub.shakespeare.lit/news announcements'>
@ -874,7 +874,8 @@ And by opposing end them?
</section2>
<section2 topic='Retrieve Subscriptions' anchor='entity-subscriptions'>
<p>A service SHOULD allow an entity to query the service to retrieve its subscriptions for all nodes at the service. In order to make the request, the requesting entity MUST send an IQ-get whose &PUBSUB; child contains an empty &lt;subscriptions/&gt; element with no attributes.</p>
<p>An entity way want to query the service to retrieve its subscriptions for all nodes at the service. Support for this feature ("retrieve-subscriptions") is RECOMMENDED.</p>
<p>In order to make the request, the requesting entity MUST send an IQ-get whose &PUBSUB; child contains an empty &lt;subscriptions/&gt; element with no attributes.</p>
<example caption='Entity requests all current subscriptions'><![CDATA[
<iq type='get'
from='francisco@denmark.lit/barracks'
@ -931,7 +932,8 @@ And by opposing end them?
]]></example>
</section2>
<section2 topic='Retrieve Affiliations' anchor='entity-affiliations'>
<p>A service SHOULD allow an entity to query the service to retrieve its affiliations for all nodes at the service. In order to make the request, the requesting entity includes an empty &lt;affiliations/&gt; element with no attributes.</p>
<p>An entity may want to query the service to retrieve its affiliations for all nodes at the service. Support for this feature ("retrieve-affiliations") is RECOMMENDED.</p>
<p>In order to make the request, the requesting entity includes an empty &lt;affiliations/&gt; element with no attributes.</p>
<example caption='Entity requests all current affiliations'><![CDATA[
<iq type='get'
from='francisco@denmark.lit/barracks'
@ -1318,7 +1320,8 @@ And by opposing end them?
]]></example>
</section3>
<section3 topic='Multiple Subscriptions' anchor='subscriber-subscribe-multi'>
<p>A service MAY allow an entity to subscribe multiple times to the same node. This enables an entity to subscribe using different subscription options. If multiple subscriptions for the same JID are allowed, the service MUST use the 'subid' attribute to differentiate between subscriptions for the same entity (therefore the SubID MUST be unique for each node+JID combination and the SubID MUST be present on the entity element any time it is sent to the subscriber). It is NOT RECOMMENDED for clients to generate SubIDs, since collisions might result; therefore a service SHOULD generate the SubID on behalf of the subscriber and MAY overwrite SubIDs if they are provided by subscribers. If the service does not allow multiple subscriptions for the same entity and it receives an additional subscription request, the service MUST return the current subscription state (as if the subscription was just approved).</p>
<p>An entity may wish to subscribe using different subscription options, which it can do by subscribing multiple times to the same node. Support for this feature ("multi-subscribe") is OPTIONAL.</p>
<p>If multiple subscriptions for the same JID are allowed, the service MUST use the 'subid' attribute to differentiate between subscriptions for the same entity (therefore the SubID MUST be unique for each node+JID combination and the SubID MUST be present on the entity element any time it is sent to the subscriber). It is NOT RECOMMENDED for clients to generate SubIDs, since collisions might result; therefore a service SHOULD generate the SubID on behalf of the subscriber and MAY overwrite SubIDs if they are provided by subscribers. If the service does not allow multiple subscriptions for the same entity and it receives an additional subscription request, the service MUST return the current subscription state (as if the subscription was just approved).</p>
</section3>
<section3 topic='Sending the Last Published Item' anchor='subscriber-subscribe-last'>
<p>When a subscription request is successfully processed, the service MAY send the last published item to the new subscriber. The message containing this item SHOULD be stamped with extended information qualified by the 'urn:xmpp:delay' namespace (see &xep0203;) to indicate it is are sent with delayed delivery. (Note that in this example the message notification is sent to the bare JID since that is the subscribed JID.)</p>
@ -1716,6 +1719,9 @@ And by opposing end them?
</pubsub>
</iq>
]]></example>
</section3>
<section3 topic='Form Processing' anchor='subscriber-configure-process'>
<section4 topic='Success' anchor='subscriber-configure-process-success'>
<p>If the service can successfully process the submission, it MUST respond with success.</p>
<example caption='Service responds with success'><![CDATA[
<iq type='result'
@ -1723,6 +1729,8 @@ And by opposing end them?
to='francisco@denmark.lit/barracks'
id='options2'/>
]]></example>
</section4>
<section4 topic='Failure' anchor='subscriber-configure-process-failure'>
<p>If the subscriber attempts to set an invalid group of options, the service MUST respond with a &badrequest; error.</p>
<example caption='Service responds with Bad Request for invalid options'><![CDATA[
<iq type='error'
@ -1753,6 +1761,9 @@ And by opposing end them?
</iq>
]]></example>
<p>The other errors already mentioned for getting subscription options also apply to setting subscription options.</p>
</section4>
</section3>
<section3 topic='Subscribe and Configure' anchor='subscriber-configure-subandconfig'>
<p>As noted, if a service supports subscription options, an entity MAY subscribe and provide the subscription options in the same stanza.</p>
<p>Note: The &lt;options/&gt; element MUST follow the &lt;subscribe/&gt; element and MUST NOT possess a 'node' attribute or 'jid' attribute, since the value of the &lt;subscribe/&gt; element's 'node' attribute specifies the desired NodeID and the value of the &lt;subscribe/&gt; element's 'jid' attribute specifies the subscriber's JID; if any of these rules are violated, the service MUST return a &badrequest; error.</p>
<example caption='Entity subscribes to node and sets configuration options'><![CDATA[
@ -2347,7 +2358,7 @@ And by opposing end them?
</event>
</message>
<message from='pubsub.shakespeare.lit' to='marcellus@denmark.lit' id='fez'>
<message from='pubsub.shakespeare.lit' to='bard@shakespeare.lit' id='fez'>
<event xmlns='http://jabber.org/protocol/pubsub#event'>
<items node='princely_musings'>
<item id='ae890ac52d0df67ed7cfdf51b644e901'>
@ -2399,7 +2410,7 @@ And by opposing end them?
</event>
</message>
<message from='pubsub.shakespeare.lit' to='marcellus@denmark.lit' id='fez'>
<message from='pubsub.shakespeare.lit' to='bard@shakespeare.lit' id='fez'>
<event xmlns='http://jabber.org/protocol/pubsub#event'>
<items node='princely_musings'>
<item id='ae890ac52d0df67ed7cfdf51b644e901'/>
@ -2653,7 +2664,7 @@ And by opposing end them?
</section2>
<section2 topic='Delete an Item from a Node' anchor='publisher-delete'>
<p>A service SHOULD allow a publisher to delete an item once it has been published to a node that supports persistent items.</p>
<p>A publisher may want to delete an item once it has been published to a node that supports persistent items. Support for this feature ("delete-any") is RECOMMENDED.</p>
<section3 topic='Request' anchor='publisher-delete-request'>
<p>To delete an item, the publisher sends a retract request as shown in the following examples. The &lt;retract/&gt; element MUST possess a 'node' attribute, MAY possess a 'notify' attribute, and SHOULD contain one &ITEM; element (but MAY contain more than one &ITEM; element for <link url='#impl-batch'>Batch Processing</link> of item retractions); the &ITEM; element MUST be empty and MUST possess an 'id' attribute.</p>
<example caption='Entity deletes an item from a node'><![CDATA[
@ -2670,7 +2681,7 @@ And by opposing end them?
]]></example>
</section3>
<section3 topic='Success Case' anchor='publisher-delete-success'>
<p>If none of the error cases occurs, the service MUST delete the item.</p>
<p>If no error occurs, the service MUST delete the item.</p>
<example caption='Service replies with success'><![CDATA[
<iq type='result'
from='pubsub.shakespeare.lit'
@ -2678,7 +2689,7 @@ And by opposing end them?
id='retract1'/>
]]></example>
<section4 topic='Delete And Notify' anchor='publisher-delete-success-notify'>
<p>If none of the error cases occurs and the &lt;retract/&gt; element included a 'notify' attribute with a value of "true" or "1" &BOOLEANNOTE;, then the service MUST delete the item and MUST send message notifications to all subscribers as shown below. The syntax is identical to publish notifications except that instead of an &ITEM; element, the notification includes a &lt;retract/&gt; element.</p>
<p>If no error occurs and the &lt;retract/&gt; element included a 'notify' attribute with a value of "true" or "1" &BOOLEANNOTE;, then the service MUST delete the item and MUST send message notifications to all subscribers as shown below. The syntax is identical to publish notifications except that instead of an &ITEM; element, the notification includes a &lt;retract/&gt; element.</p>
<example caption='Subscribers are notified of deletion'><![CDATA[
<message from='pubsub.shakespeare.lit' to='francisco@denmark.lit' id='foo'>
<event xmlns='http://jabber.org/protocol/pubsub#event'>
@ -2842,7 +2853,7 @@ And by opposing end them?
<section1 topic='Owner Use Cases' anchor='owner'>
<section2 topic='Create a Node' anchor='owner-create'>
<section3 topic='General Considerations' anchor='owner-create-general'>
<p>A service SHOULD allow entities to create new nodes. However, a service MAY disallow creation of nodes based on the identity of the requesting entity, or MAY disallow node creation altogether (e.g., reserving that privilege to a service-wide administrator).</p>
<p>An entity may want to create a new node. Support for this feature ("create-nodes") is RECOMMENDED. However, a service MAY disallow creation of nodes based on the identity of the requesting entity, or MAY disallow node creation altogether (e.g., reserving that privilege to a service-wide administrator).</p>
<p>There are two ways to create a node:</p>
<ol>
<li>Create a node with default configuration for the specified node type.</li>
@ -3074,7 +3085,8 @@ And by opposing end them?
</section3>
</section2>
<section2 topic='Configure a Node' anchor='owner-configure'>
<p>After creating a new node, the node owner may want to modify the node configuration. The process for doing so is shown below.</p>
<p>After creating a new node, the node owner may want to modify the node configuration. Support for this feature is RECOMMENDED.</p>
<section3 topic='Request' anchor='owner-configure-request'>
<example caption='Owner requests configuration form'><![CDATA[
<iq type='get'
from='hamlet@denmark.lit/elsinore'
@ -3085,6 +3097,9 @@ And by opposing end them?
</pubsub>
</iq>
]]></example>
</section3>
<section3 topic='Success Case' anchor='owner-configure-success'>
<p>If no error occurs, the server MUST return an empty configuration form to the node owner.</p>
<p>Note: The following example shows some of the possible configuration options that MAY be provided. If an implementation implements these features using the <strong>Data Forms</strong> protocol, that implementation MUST use the fields that are registered with the XMPP Registrar in association with the 'http://jabber.org/protocol/pubsub' namespace (a preliminary representation of those field variables is shown below and in the <link url='#registrar-formtypes-config'>pubsub#node_config FORM_TYPE</link> section of this document, but MUST NOT be construed as canonical, since the XMPP Registrar may standardize additional fields at a later date without changes to this document). An implementation MAY choose to specify different labels, values, and even field types, but MUST conform to the defined variable naming scheme.</p>
<example caption='Service responds with configuration form'><![CDATA[
<iq type='result'
@ -3182,6 +3197,8 @@ And by opposing end them?
</pubsub>
</iq>
]]></example>
</section3>
<section3 topic='Error Cases' anchor='owner-configure-error'>
<p>There are several reasons why the node configuration request might fail:</p>
<ol>
<li>The service does not support node configuration.</li>
@ -3191,6 +3208,7 @@ And by opposing end them?
<li>The specified node does not exist.</li>
</ol>
<p>These error cases are described more fully in the following sections.</p>
<section4 topic='Node Configuration Not Supported' anchor='owner-configure-error-notsupported'>
<p>If the service does not support node configuration, the service MUST return a &feature; error, specifying a pubsub-specific error condition of &lt;unsupported/&gt; and a feature of "config-node".</p>
<example caption='Service does not support node configuration'><![CDATA[
<iq type='error'
@ -3207,6 +3225,8 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
<section4 topic='Insufficient Privileges' anchor='owner-configure-error-forbidden'>
<p>If the requesting entity does not have sufficient privileges to configure the node, the service MUST respond with a &forbidden; error.</p>
<example caption='Requesting entity is prohibited from configuring this node'><![CDATA[
<iq type='error'
@ -3221,6 +3241,8 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
<section4 topic='NodeID Required' anchor='owner-configure-error-nodeid'>
<p>If the request did not specify a node, the service SHOULD return a &badrequest; error. It is possible that by not including a NodeID, the requesting entity is asking to configure the root node; however, if the requesting entity is not a service-level admin, it makes sense to return &badrequest; instead of &forbidden;.</p>
<example caption='Request did not specify a node'><![CDATA[
<iq type='error'
@ -3236,6 +3258,8 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
<section4 topic='No Configuration Options' anchor='owner-configure-error-options'>
<p>If no configuration options are available (e.g., because node configuration is "locked down"), the service MUST return a &notallowed; error to the owner.</p>
<example caption='Node has no configuration options'><![CDATA[
<iq type='error'
@ -3250,6 +3274,8 @@ And by opposing end them?
</error>
</iq>
]]></example>
<section4 topic='Node Does Not Exist' anchor='owner-configure-error-node'>
</section4>
<p>If the node does not exist, the service MUST return an &notfound; error.</p>
<example caption='Node does not exist'><![CDATA[
<iq type='error'
@ -3264,6 +3290,9 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
</section3>
<section3 topic='Form Submission' anchor='owner-configure-submit'>
<p>After receiving the configuration form, the owner SHOULD submit a completed configuration form.</p>
<example caption='Owner submits node configuration form'><![CDATA[
<iq type='set'
@ -3297,12 +3326,6 @@ And by opposing end them?
</configure>
</pubsub>
</iq>
]]></example>
<example caption='Service replies with success'><![CDATA[
<iq type='result'
from='pubsub.shakespeare.lit'
to='hamlet@denmark.lit/elsinore'
id='config2'/>
]]></example>
<p>Alternatively, the owner MAY cancel the configuration process, in which case the existing configuration MUST be applied.</p>
<example caption='Owner cancels configuration process'><![CDATA[
@ -3317,6 +3340,18 @@ And by opposing end them?
</pubsub>
</iq>
]]></example>
</section3>
<section3 topic='Form Processing' anchor='owner-configure-process'>
<section4 topic='Success' anchor='owner-configure-process-success'>
<p>If the form can be successfully processed, the service MUST return an IQ-result.</p>
<example caption='Service replies with success'><![CDATA[
<iq type='result'
from='pubsub.shakespeare.lit'
to='hamlet@denmark.lit/elsinore'
id='config2'/>
]]></example>
</section4>
<section4 topic='Failure' anchor='owner-configure-process-failure'>
<p>If the requested node configuration change cannot be processed (e.g., because the node owner has attempted to change the configuration so that there are no node owners), the service MUST return a &notacceptable; error to the owner.</p>
<example caption='Configuration change cannot be processed'><![CDATA[
<iq type='error'
@ -3331,6 +3366,8 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
<section4 topic='Success With Notifications' anchor='owner-configure-process-notify'>
<p>If the "pubsub#notify_config" option is set to true, the service MUST send a notification of configuration change to all subscribers. (A service SHOULD support this option for leaf nodes and MUST support it for <link url='#collection'>Collection Nodes</link>.) If the node configuration is set to event notifications only, the notification MUST consist of an empty &lt;configuration/&gt; element whose 'node' attribute is set to the NodeID of the node; if the node configuration is set to full payloads, the &lt;configuration/&gt; element MUST in addition contain the node configuration as represented via the <strong>Data Forms</strong> protocol.</p>
<example caption='Service sends configuration change notification (event notification only)'><![CDATA[
<message from='pubsub.shakespeare.lit' to='francisco@denmark.lit' id='foo'>
@ -3370,9 +3407,13 @@ And by opposing end them?
</event>
</message>
]]></example>
</section4>
</section3>
</section2>
<section2 topic='Request Default Configuration Options' anchor='owner-default'>
<p>A service MAY allow entities to determine the default node configuration for new nodes created on the service, in order to help entities determine whether they want to perform create-and-configure as previously described. To get the options, the entity MUST send an empty &lt;default/&gt; element to the service with no NodeID; in response, the service SHOULD return the default node options.</p>
<p>An entity way want to request information about the default node configuration, e.g. in order to determine whether to perform create-and-configure as previously described. Support for this feature is OPTIONAL.</p>
<section3 topic='Request' anchor='owner-default-request'>
<p>To get the options, the entity MUST send an empty &lt;default/&gt; element to the service with no NodeID; in response, the service SHOULD return the default node options.</p>
<example caption='Entity requests default configuration options'><![CDATA[
<iq type='get'
from='hamlet@denmark.lit/elsinore'
@ -3383,6 +3424,9 @@ And by opposing end them?
</pubsub>
</iq>
]]></example>
</section3>
<section3 topic='Success Case' anchor='owner-default-success'>
<p>If no error occurs, the service MUST return the default configuration options.</p>
<example caption='Service responds with default configuration options'><![CDATA[
<iq type='result'
from='hamlet@denmark.lit/elsinore'
@ -3472,12 +3516,15 @@ And by opposing end them?
</pubsub>
</iq>
]]></example>
</section3>
<section3 topic='Error Cases' anchor='owner-default-error'>
<p>There are several reasons why the default node configuration options request might fail:</p>
<ol>
<li>The service does not support node configuration.</li>
<li>The service does not support retrieval of default node configuration.</li>
</ol>
<p>These error cases are described more fully in the following sections.</p>
<section4 topic='Node Configuration Not Supported' anchor='owner-default-error-noconfig'>
<p>If the service does not support node configuration, it MUST return a &feature; error, specifying a pubsub-specific error condition of &lt;unsupported/&gt; and a feature of "config-node".</p>
<example caption='Service does not support node configuration'><![CDATA[
<iq type='error'
@ -3494,6 +3541,8 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
<section4 topic='Default Configuration Retrieval Not Supported' anchor='owner-default-error-notsupported'>
<p>If the service does not support retrieval of default node configuration options, it MUST return a &feature; error, specifying a pubsub-specific error condition of &lt;unsupported/&gt; and a feature of "retrieve-default".</p>
<example caption='Service does not support retrieval of default configuration options'><![CDATA[
<iq type='error'
@ -3510,6 +3559,9 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
</section3>
<section3 topic='Requesting Collection Node Configuration' anchor='owner-default-requestcollection'>
<p>The default configuration options may be different for a collection node vs. a leaf node. In order to specifically request the default configuration options for collection nodes, an entity MUST include a Data Form with a 'pubsub#node_type' field whose value is "collection" in the request (since the default value for the 'pubsub#node_type' field is "leaf").</p>
<example caption='Entity requests default configuration options for collection nodes'><![CDATA[
<iq type='get'
@ -3550,9 +3602,11 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section3>
</section2>
<section2 topic='Delete a Node' anchor='owner-delete'>
<p>If a service supports node creation, it MUST support node deletion. If an implementation persists items, it MUST remove all items from persistent storage before the node itself is deleted.</p>
<section3 topic='Request' anchor='owner-delete-request'>
<p>In order to delete a node, a node owner MUST send a node deletion request, consisting of a &lt;delete/&gt; element whose 'node' attribute specifies the NodeID of the node to be deleted.</p>
<example caption='Owner deletes a node'><![CDATA[
<iq type='set'
@ -3564,6 +3618,8 @@ And by opposing end them?
</pubsub>
</iq>
]]></example>
</section3>
<section3 topic='Success Case' anchor='owner-delete-success'>
<p>If no error occurs, the service MUST inform the owner of success.</p>
<example caption='Service replies with success'><![CDATA[
<iq type='result'
@ -3583,11 +3639,10 @@ And by opposing end them?
<delete node='princely_musings'/>
</event>
</message>
.
.
.
]]></example>
<p>If the deleted node is a <link url='#collections'>Collection Node</link>, the implementation MAY associate the "orphaned" leaf nodes with the root collection node or associate them with no collection node.</p>
</section3>
<section3 topic='Error Cases' anchor='owner-delete-error'>
<p>There are several reasons why the node deletion request might fail:</p>
<ol>
<li>The requesting entity does not have sufficient privileges to delete the node.</li>
@ -3595,6 +3650,7 @@ And by opposing end them?
<li>The specified node does not exist.</li>
</ol>
<p>These error cases are described more fully in the following sections.</p>
<section4 topic='Insufficient Privileges' anchor='owner-delete-error-forbidden'>
<p>If the requesting entity does not have sufficient privileges to delete the node (e.g., is not an owner), the service MUST return a &forbidden; error.</p>
<example caption='Entity is not an owner'><![CDATA[
<iq type='error'
@ -3609,6 +3665,8 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
<section4 topic='Root Collection Node' anchor='owner-delete-error-root'>
<p>If the requesting entity attempts to delete the root collection node, the service MUST return a &notallowed; error.</p>
<example caption='Node is the root'><![CDATA[
<iq type='error'
@ -3623,6 +3681,8 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
<section4 topic='Node Does Not Exist' anchor='owner-delete-error-node'>
<p>If the requesting entity attempts to delete a node that does not exist, the service MUST return an &notfound; error.</p>
<example caption='Owner attempts to delete a non-existent node'><![CDATA[
<iq type='error'
@ -3637,10 +3697,13 @@ And by opposing end them?
</error>
</iq>
]]></example>
<p>If the deleted node is a <link url='#collections'>Collection Node</link>, the implementation MAY associate the "orphaned" leaf nodes with the root collection node or associate them with no collection node.</p>
</section4>
</section3>
</section2>
<section2 topic='Purge All Node Items' anchor='owner-purge'>
<p>If a service persists published items, it MAY enable node owners to purge the node of all published items (thus removing all items from the persistent store, with the exception of the last published item, which MAY be cached). In order to purge a node of all items, a node owner MUST send a node purge request, consisting of a &lt;purge/&gt; element whose 'node' attribute specifies the NodeID of the node to be purged.</p>
<p>If a service persists published items, a node owner may want to purge the node of all published items (thus removing all items from the persistent store, with the exception of the last published item, which MAY be cached). It is OPTIONAL for a service to implement this feature.</p>
<section3 topic='Request' anchor='owner-purge-request'>
<p>In order to purge a node of all items, a node owner sends a node purge request consisting of a &lt;purge/&gt; element whose 'node' attribute specifies the NodeID of the node to be purged.</p>
<example caption='Owner purges all items from a node'><![CDATA[
<iq type='set'
from='hamlet@denmark.lit/elsinore'
@ -3651,6 +3714,8 @@ And by opposing end them?
</pubsub>
</iq>
]]></example>
</section3>
<section3 topic='Success Case' anchor='owner-purge-success'>
<p>If no error occurs, the service MUST purge the node and inform the owner of success.</p>
<example caption='Service replies with success'><![CDATA[
<iq type='result'
@ -3670,11 +3735,9 @@ And by opposing end them?
<purge node='princely_musings'/>
</event>
</message>
.
.
.
]]></example>
</section3>
<section3 topic='Error Cases' anchor='owner-purge-error'>
<p>There are several reasons why the node purge request might fail:</p>
<ol>
<li>The node or service does not support node purging.</li>
@ -3683,6 +3746,7 @@ And by opposing end them?
<li>The specified node does not exist.</li>
</ol>
<p>These error cases are described more fully in the following sections.</p>
<section4 topic='Node Purging Not Supported' anchor='owner-purge-error-notsupported'>
<p>If the node or service does not support node purging, it MUST return a &feature; error, specifying a pubsub-specific error condition of &lt;unsupported/&gt; and a feature of "purge-nodes".</p>
<example caption='Service does not support node purging'><![CDATA[
<iq type='error'
@ -3699,6 +3763,8 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
<section4 topic='Insufficient Privileges' anchor='owner-purge-error-forbidden'>
<p>If the requesting entity does not have sufficient privileges to purge the node (e.g., because it is not a node owner), the service MUST return a &forbidden; error.</p>
<example caption='Entity is not an owner'><![CDATA[
<iq type='error'
@ -3712,6 +3778,8 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
<section4 topic='Node Does Not Persist Items' anchor='owner-purge-error-nopersist'>
<p>If the service or node does not persist items (e.g., because the node is a collection node), it MUST return a &feature; error, specifying a pubsub-specific error condition of &lt;unsupported/&gt; and a feature of "persistent-items".</p>
<example caption='Node is not configured for persistent items'><![CDATA[
<iq type='error'
@ -3727,6 +3795,8 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
<section4 topic='Node Does Not Exist' anchor='owner-purge-error-node'>
<p>If the node does not exist, the service MUST return an &notfound; error.</p>
<example caption='Node does not exist'><![CDATA[
<iq type='error'
@ -3740,6 +3810,8 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
</section3>
</section2>
<section2 topic='Manage Subscription Requests' anchor='owner-subreq'>
@ -3847,8 +3919,11 @@ And by opposing end them?
</message>
]]></example>
<p>The service MUST check the "pubsub#allow" field to see if the subscription should be allowed or denied. If the owner cancels the Data Form, then the subscription request MUST remain in the pending state.</p>
<section3 topic='Request All Pending Subscription Requests' anchor='owner-subreq-all'>
<p>A service MAY allow owners to request all the current pending subscription requests for all of their nodes at the service. Implementations MUST use the &xep0050; protocol to provide this functionality. The command name ('node' attribute of the command element) MUST have a value of "http://jabber.org/protocol/pubsub#get-pending".</p>
</section2>
<section2 topic='Process Pending Subscription Requests' anchor='owner-subreq'>
<p>A node owner may want to request all of the pending subscription requests for all of their nodes at a service. It is OPTIONAL for a service to implement this feature.</p>
<p>This feature MUST be implemented using the &xep0050; protocol, where the command name ('node' attribute of the command element) MUST have a value of "http://jabber.org/protocol/pubsub#get-pending".</p>
<section3 topic='Request' anchor='owner-subreq-request'>
<example caption='Owner requests pending subscription requests'><![CDATA[
<iq type='set'
from='hamlet@denmark.lit/elsinore'
@ -3859,6 +3934,8 @@ And by opposing end them?
action='execute'/>
</iq>
]]></example>
</section3>
<section3 topic='Success Case' anchor='owner-subreq-success'>
<p>If no error occurs, the service SHOULD return a data form for managing subscription requests, which MUST contain a single field with a 'var' attribute value of "node" whose &lt;option/&gt; elements specify the nodes for which the requesting entity has subscription approval privileges (as an optimization, the service MAY specify only the nodes that have subscription requests pending).</p>
<example caption='Service responds with data form to be populated'><![CDATA[
<iq type='result'
@ -3879,6 +3956,8 @@ And by opposing end them?
</command>
</iq>
]]></example>
</section3>
<section3 topic='Error Cases' anchor='owner-subreq-error'>
<p>There are several reasons why the pending subscription approval request might fail:</p>
<ol>
<li>The service does not support the ad-hoc commands protocol.</li>
@ -3887,6 +3966,7 @@ And by opposing end them?
<li>The specified node does not exist.</li>
</ol>
<p>These error cases are described more fully in the following sections.</p>
<section4 topic='Ad-Hoc Commands Not Supported' anchor='owner-subreq-error-adhoc'>
<p>If the service does not support the ad-hoc commands protocol, it MUST respond with a &unavailable; error.</p>
<example caption='Service responds with node not found'><![CDATA[
<iq type='error'
@ -3901,6 +3981,8 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
<section4 topic='Get-Pending Not Supported' anchor='owner-subreq-error-getpending'>
<p>If the service does not support the "get-pending" feature, it MUST respond with a &feature; error, specifying a pubsub-specific error condition of &lt;unsupported/&gt; and a feature of "get-pending".</p>
<example caption='Service responds with node not found'><![CDATA[
<iq type='error'
@ -3917,6 +3999,8 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
<section4 topic='Insufficient Privileges' anchor='owner-subreq-error-forbidden'>
<p>If the requesting entity does not have sufficient privileges to approve subscription requests, the service MUST respond with a &forbidden; error.</p>
<example caption='Entity does not have sufficient privileges to approve subscription requests'><![CDATA[
<iq type='error'
@ -3931,6 +4015,8 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
<section4 topic='Node Does Not Exist' anchor='owner-subreq-error-node'>
<p>If the requested node does not exist, the service MUST respond with an &notfound; error.</p>
<example caption='Service responds with node not found'><![CDATA[
<iq type='error'
@ -3945,6 +4031,9 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
</section3>
<section3 topic='Per-Node Request' anchor='owner-subreq-pernode'>
<p>Upon receiving the data form for managing subscription requests, the owner then MAY request pending subscription approval requests for a given node.</p>
<example caption='Owner requests all pending subscription requests for a node'><![CDATA[
<iq type='set' to='pubsub.shakespeare.lit' id='pending2'>
@ -3968,13 +4057,14 @@ And by opposing end them?
id='pending2'/>
]]></example>
<p>The service shall then send one subscription approval message for each pending subscription request, as shown above for a single pending subscription request.</p>
<p>Note: A service SHOULD conform to its affiliation policies in maintaining the list of pending subscriptions. In particular, if the affiliation of an entity with a pending subscription is modified to owner or publisher, the service SHOULD automatically approve the subscription request and remove the entity's previous request from the pending list. Similarly, if the affiliation of an entity with a pending subscription is modified to outcast, the service SHOULD automatically reject the subscription request and remove the entity's previous request from the pending list.</p>
<p>If an entity's subscription request is denied, the service SHOULD send a &MESSAGE; to the entity, where the message conforms to the format described in the <link url='#impl-unsub'>Notification of Subscription Denial or Cancellation</link> section of this document.</p>
<p>Note: A service SHOULD conform to its affiliation policies in maintaining the list of pending subscriptions. In particular, if the affiliation of an entity with a pending subscription is modified to owner or publisher, the service SHOULD automatically approve the subscription request and remove the entity's previous request from the pending list. Similarly, if the affiliation of an entity with a pending subscription is modified to outcast, the service SHOULD automatically reject the subscription request and remove the entity's previous request from the pending list. (If an entity's subscription request is denied, the service SHOULD send a &MESSAGE; to the entity, where the message conforms to the format described in the <link url='#impl-unsub'>Notification of Subscription Denial or Cancellation</link> section of this document.)</p>
</section3>
</section2>
<section2 topic='Manage Subscriptions' anchor='owner-subscriptions'>
<p>A service MAY allow a node owner to edit the list of subscriptions associated with a given node and to set subscriptions for new entities (for nodes of type "whitelist", this enables the node owner to add subscribers); if so, it MUST advertise support for the "pubsub#manage-subscriptions" feature.</p>
<p>A node owner may want to edit the list of subscriptions associated with a given node. Support for this feature ("pubsub#manage-subscriptions") is OPTIONAL.</p>
<p>Note: This feature enables a node owner to set subscriptions for new entities; for nodes of type "whitelist", this enables the node owner to add subscribers.</p>
<section3 topic='Request' anchor='owner-subscriptions-request'>
<p>In order to request a list of all subscriptions, a node owner MUST send a subscriptions request, consisting of a &lt;subscriptions/&gt; element whose 'node' attribute specifies the NodeID of the relevant node.</p>
<example caption='Owner requests all subscriptions'><![CDATA[
<iq type='get'
@ -3986,6 +4076,8 @@ And by opposing end them?
</pubsub>
</iq>
]]></example>
</section3>
<section3 topic='Success Case' anchor='owner-subscriptions-success'>
<p>If no error occurs, the service MUST return the list of subscriptions for entities whose subscription state is "subscribed" or "unconfigured" (it MUST NOT return entities whose subscription state is "none" and SHOULD NOT return entities whose subscription state is "pending"). The result MAY specify multiple &lt;subscription/&gt; elements for the same entity (JID), but each element MUST possess a distinct value of the 'subid' attribute (as shown below).</p>
<example caption='Service returns list of subscriptions'><![CDATA[
<iq type='result'
@ -4002,6 +4094,8 @@ And by opposing end them?
</pubsub>
</iq>
]]></example>
</section3>
<section3 topic='Error Cases' anchor='owner-subscriptions-error'>
<p>There are several reasons why the manage subscriptions request might fail:</p>
<ol>
<li>The service does not support subscription management.</li>
@ -4009,6 +4103,7 @@ And by opposing end them?
<li>The specified node does not exist.</li>
</ol>
<p>These error cases are described more fully in the following sections.</p>
<section4 topic='Subscription Management Not Supported' anchor='owner-subscriptions-error-notsupported'>
<p>If an implementation does not support subscription management, it MUST return a &feature; error, specifying a pubsub-specific error condition of &lt;unsupported/&gt; and a feature of "manage-subscriptions".</p>
<example caption='Node or service does not support subscription management'><![CDATA[
<iq type='error'
@ -4024,6 +4119,8 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
<section4 topic='Insufficient Privileges' anchor='owner-subscriptions-error-forbidden'>
<p>If the requesting entity is not a node owner, the service MUST return a &forbidden; error.</p>
<example caption='Entity is not an owner'><![CDATA[
<iq type='error'
@ -4037,6 +4134,8 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
<section4 topic='Node Does Not Exist' anchor='owner-subscriptions-error-node'>
<p>If the node does not exist, the service MUST return an &notfound; error.</p>
<example caption='Node does not exist'><![CDATA[
<iq type='error'
@ -4050,6 +4149,9 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
</section3>
<section3 topic='Modifying Subscriptions' anchor='owner-subscriptions-modify'>
<p>Upon receiving the subscriptions list, the node owner MAY modify subscription states. The owner MUST send only modified subscription states (i.e., a "delta"), not the complete list. (Note: If the 'subscription' attribute is not specified in a modification request, then the value MUST NOT be changed.)</p>
<example caption='Owner modifies subscriptions'><![CDATA[
<iq type='set'
@ -4068,7 +4170,11 @@ And by opposing end them?
from='pubsub.shakespeare.lit'
id='subman2'/>
]]></example>
</section3>
<section3 topic='Deleting a Subscriber' anchor='owner-subscriptions-delete'>
<p>In order to remove an entity from the subscriptions list, the owner MUST set the value of the 'subscription' attribute to "none" and the service MUST remove that entity from the subscriptions list and not return it in response to future list requests.</p>
</section3>
<section3 topic='Multiple Simultaneous Modifications' anchor='owner-subscriptions-multi'>
<p>The owner MAY change multiple subscriptions in a single request. If one of the entity elements specified is invalid, the service MUST return an IQ error (which SHOULD be &notacceptable;) with the invalid entries, where the subscription returned is the original, un-altered subscription.</p>
<example caption='Owner sets subscription for multiple entities'><![CDATA[
<iq type='set'
@ -4099,6 +4205,8 @@ And by opposing end them?
</iq>
]]></example>
<p>If errors occur during a modification request for multiple entities, the pubsub service MUST return any &lt;subscription/&gt; element(s) which caused the error. Returned entities which failed to be modified MUST include the existing 'subscription' attribute. Any entity elements which are not returned in an IQ error case MUST be treated as successful modifications. The owner MAY specify multiple &lt;subscription/&gt; elements for the same entity, but each element MUST possess a distinct value of the 'subid' attribute.</p>
</section3>
<section3 topic='Notifying Subscribers' anchor='owner-subscriptions-notify'>
<p>An implementation SHOULD send notification to an entity whose subscription has changed (see the <link url='#impl-subchange'>Notification of Subscription State Changes</link> section of this document).</p>
<example caption='Service sends notification of subscription change'><![CDATA[
<message from='pubsub.shakespeare.lit' to='polonius@denmark.lit'>
@ -4107,10 +4215,12 @@ And by opposing end them?
</pubsub>
</message>
]]></example>
</section3>
</section2>
<section2 topic='Manage Affiliations' anchor='owner-affiliations'>
<p>A service MAY allow a node owner to edit the affiliations of entities associated with a given node and to set affiliations for new entities; if so, it MUST advertise support for the "pubsub#modify-affiliations" feature.</p>
<p>A node owner may want to edit the affiliations of entities associated with a given node and to set affiliations for new entities. Support for this feature ("pubsub#modify-affiliations") is OPTIONAL.</p>
<section3 topic='Request' anchor='owner-affiliations-request'>
<p>In order to request a list of all affiliated entities, a node owner MUST send an affiliations request, consisting of an &lt;affiliations/&gt; element whose 'node' attribute specifies the NodeID of the relevant node.</p>
<example caption='Owner requests all affiliated entities'><![CDATA[
<iq type='get'
@ -4122,6 +4232,8 @@ And by opposing end them?
</pubsub>
</iq>
]]></example>
</section3>
<section3 topic='Success Case' anchor='owner-affiliations-success'>
<p>If no error occurs, the service MUST return the list of entities whose affiliation is "owner", "publisher", or "outcast" (it MUST NOT return entities whose affiliation is "none").</p>
<example caption='Service returns list of affiliated entities'><![CDATA[
<iq type='result'
@ -4136,6 +4248,8 @@ And by opposing end them?
</pubsub>
</iq>
]]></example>
</section3>
<section3 topic='Error Cases' anchor='owner-affiliations-error'>
<p>There are several reasons why the affiliated entities request might fail:</p>
<ol>
<li>The service does not support modification of affiliations.</li>
@ -4143,6 +4257,7 @@ And by opposing end them?
<li>The specified node does not exist.</li>
</ol>
<p>These error cases are described more fully in the following sections.</p>
<section4 topic='Affiliation Modification Not Supported' anchor='owner-affiliations-notsupported'>
<p>If an implementation does not support modification of affiliations, it MUST return a &feature; error, specifying a pubsub-specific error condition of &lt;unsupported/&gt; and a feature of "modify-affiliations".</p>
<example caption='Node or service does not support affiliation management'><![CDATA[
<iq type='error'
@ -4158,6 +4273,8 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
<section4 topic='Insufficient Privileges' anchor='owner-affiliations-forbidden'>
<p>If the requesting entity is not a node owner, the service MUST return a &forbidden; error.</p>
<example caption='Entity is not an owner'><![CDATA[
<iq type='error'
@ -4171,6 +4288,8 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
<section4 topic='Node Does Not Exist' anchor='owner-affiliations-node'>
<p>If the node does not exist, the service MUST return an &notfound; error.</p>
<example caption='Node does not exist'><![CDATA[
<iq type='error'
@ -4184,6 +4303,9 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
</section3>
<section3 topic='Modifying Affiliations' anchor='owner-affiliations-modify'>
<p>Upon receiving the affiliations list, the node owner MAY modify affiliations. The owner MUST send only modified affiliations (i.e., a "delta"), not the complete list. (Note: If the 'affiliation' attribute is not specified in a modification request, then the value MUST NOT be changed.)</p>
<example caption='Owner modifies affiliations'><![CDATA[
<iq type='set'
@ -4204,7 +4326,11 @@ And by opposing end them?
from='pubsub.shakespeare.lit'
id='ent2'/>
]]></example>
</section3>
<section3 topic='Deleting an Entity' anchor='owner-affiliations-delete'>
<p>In order to remove an entity from the affiliations list, the owner MUST set the value of the 'affiliation' attribute to "none" and the service MUST remove that entity from the affiliations list and not return it in response to future list requests.</p>
</section3>
<section3 topic='Multiple Simultaneous Modifications' anchor='owner-affiliations-multi'>
<p>The owner MAY change multiple affiliations in a single request. If one of the entity elements specified is invalid, the service MUST return an IQ error (which SHOULD be &notacceptable;) with the invalid entries, where the affiliation returned is the original, un-altered affiliation.</p>
<p>The following example shows an entity attempting to make the owner something other than an affiliation of "owner", an action which MUST NOT be allowed if there is only one owner.</p>
<example caption='Owner sets affiliation for multiple entities'><![CDATA[
@ -4237,6 +4363,8 @@ And by opposing end them?
</iq>
]]></example>
<p>The state chart at the beginning of this document is a MUST-IMPLEMENT set of rules for checking possible state transitions. Implementations MAY enforce other (more strict) rules. If errors occur during a modification request for multiple entities, the pubsub service MUST return any &lt;affiliation/&gt; element(s) which caused the error. Returned entities which failed to be modified MUST include the existing 'affiliation' attribute. Any entity elements which are not returned in an IQ error case MUST be treated as successful modifications. The owner MUST NOT specify multiple &lt;affiliation/&gt; elements for the same entity; otherwise the service MUST return a &badrequest; error.</p>
</section3>
<section3 topic='Notifying Entities' anchor='owner-affiliations-notify'>
<p>An implementation MAY send a message to an entity whose affiliation has changed, which MAY contain a &BODY; element specifying natural-language text regarding the affiliation change and which SHOULD contain the modified affiliation data.</p>
<example caption='Service sends notification of affiliation change'><![CDATA[
<message from='pubsub.shakespeare.lit' to='polonius@denmark.lit'>
@ -4247,6 +4375,7 @@ And by opposing end them?
</pubsub>
</message>
]]></example>
</section3>
</section2>
</section1>
@ -4454,6 +4583,7 @@ And by opposing end them?
</section2>
<section2 topic='Create a Node Associated with a Collection' anchor='collections-createassociated'>
<section3 topic='Request' anchor='collections-createassociated-request'>
<p>To create a new node and associate it with an existing collection, the node configuration protocol MUST be used in the node creation request (see the <link url='#owner-create-and-configure'>Create and Configure a Node</link> section of this document). In order to specify the associated collection(s), the form MUST include a 'pubsub#collection' field.</p>
<p>Note: Inclusion of the node configuration form is not necessary if the node is being created as a first-level child of the root collection node, since every such child is automatically affiliated with the root collection node (if any).</p>
<p>Note: For the protocol used to associate an existing node with a collection, refer to the <link url='#collections-associate'>Associate an Existing Node with a Collection</link> section of this document.</p>
@ -4472,8 +4602,12 @@ And by opposing end them?
</pubsub>
</iq>
]]></example>
<p>The service then creates the node and associates it with the collection.</p>
<p>Note: If the node is a collection node and the requesting entity wishes to request the default configuration, the requesting entity MUST include <em>only</em> the "pubsub#collection" and "pubsub#node_type" fields in the configuration form.</p>
</section3>
<section3 topic='Success Case' anchor='collections-createassociated-success'>
<p>If no error occurs, the service MUST create the node and associate it with the collection.</p>
</section3>
<section3 topic='Error Cases' anchor='collections-createassociated-error'>
<p>There are several reasons why the request might fail:</p>
<ol>
<li>The request specified more than one collection node, but the service allows a node to be associated with only one collection node.</li>
@ -4483,6 +4617,7 @@ And by opposing end them?
<li>The specified collection node does not exist.</li>
</ol>
<p>These error cases are described more fully in the following sections.</p>
<section4 topic='Only One Collection Node' anchor='collections-createassociated-error-onenode'>
<p>An implementation MAY allow a node to be associated with more than one collection node and therefore MAY specify a type of "text-multi" for the "pubsub#collection" field. However, in order to reduce the complexity of implementation, it is RECOMMENDED to allow only one parent collection node for each node and therefore it is RECOMMENDED to specify a type of "text-single" for the "pubsub#collection" field. If a service supports associating a node with multiple collections, it MUST advertise support for the "multi-collection" feature (if that feature is not advertised, entities SHOULD assume that the service allows a node to be associated with only one collection). If the request specifies more than one collection node but the service allows a node to be associated with only one collection node, the service MUST return a &badrequest; error.</p>
<example caption='Too many collection nodes'><![CDATA[
<iq type='error'
@ -4508,6 +4643,8 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
<section4 topic='Insufficient Privileges' anchor='collections-createassociated-error-forbidden'>
<p>If the requesting entity does not have sufficient privileges to associate a node with the specified collection node, the service MUST return a &forbidden; error.</p>
<example caption='Insufficient privileges'><![CDATA[
<iq type='error'
@ -4527,6 +4664,8 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
<section4 topic='No More Nodes' anchor='collections-createassociated-error-nomore'>
<p>If no additional nodes can be associated with the collection node because a configurable limit of associated nodes has been reached, the service MUST return a &conflict; error, which SHOULD also include a pubsub-specific error condition of &lt;max-nodes-exceeded/&gt;.</p>
<example caption='Associated node limit reached'><![CDATA[
<iq type='error'
@ -4547,6 +4686,8 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
<section4 topic='Leaf Node' anchor='collections-createassociated-error-leaf'>
<p>If the specified collection node is actually a leaf node, the service MUST return an &notallowed; error.</p>
<example caption='Collection node is actually a leaf node'><![CDATA[
<iq type='error'
@ -4566,6 +4707,8 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
<section4 topic='Node Does Not Exist' anchor='collections-createassociated-error-node'>
<p>If the specified collection node does not exist, the service MUST return an &notfound; error.</p>
<example caption='No such collection node'><![CDATA[
<iq type='error'
@ -4585,6 +4728,8 @@ And by opposing end them?
</error>
</iq>
]]></example>
</section4>
</section3>
</section2>
<section2 topic='Associate an Existing Node with a Collection' anchor='collections-associate'>
@ -5046,7 +5191,7 @@ And by opposing end them?
<td>multi-subscribe</td>
<td>A single entity may subscribe to a node multiple times.</td>
<td>OPTIONAL</td>
<td>&#160;</td>
<td><link url='#subscriber-subscribe-multi'>Multiple Subscriptions</link></td>
</tr>
<tr>
<td>outcast-affiliation</td>
@ -5528,7 +5673,7 @@ And by opposing end them?
<p>A fictional example of the subscription options configuration process for content-based pubsub is shown below.</p>
<example caption='A content-based subscription'><![CDATA[
<iq type='set'
from='marcellus@denmark.lit/castle'
from='bard@shakespeare.lit/globe'
to='pubsub.shakespeare.lit'
id='filter1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
@ -5540,12 +5685,12 @@ And by opposing end them?
<iq type='result'
from='pubsub.shakespeare.lit'
to='marcellus@denmark.lit/castle'
to='bard@shakespeare.lit/globe'
id='filter1'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<subscription
node='princely_musings'
jid='marcellus@denmark.lit'
jid='bard@shakespeare.lit'
subid='991d7fd1616fd041015064133cd097a10030819e'
subscription='unconfigured'>
<subscribe-options>
@ -5556,23 +5701,23 @@ And by opposing end them?
</iq>
<iq type='get'
from='marcellus@denmark.lit/castle'
from='bard@shakespeare.lit/globe'
to='pubsub.shakespeare.lit'
id='filter2'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<options node='princely_musings'
jid='marcellus@denmark.lit'
jid='bard@shakespeare.lit'
subid='991d7fd1616fd041015064133cd097a10030819e'/>
</pubsub>
</iq>
<iq type='result'
from='pubsub.shakespeare.lit'
to='marcellus@denmark.lit/castle'
to='bard@shakespeare.lit/globe'
id='filter2'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<options node='princely_musings'
jid='marcellus@denmark.lit'
jid='bard@shakespeare.lit'
subid='991d7fd1616fd041015064133cd097a10030819e'>
<x xmlns='jabber:x:data' type='form'>
<field var='FORM_TYPE' type='hidden'>
@ -5589,12 +5734,12 @@ And by opposing end them?
</iq>
<iq type='set'
from='marcellus@denmark.lit/castle'
from='bard@shakespeare.lit/globe'
to='pubsub.shakespeare.lit'
id='filter3'>
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
<options node='princely_musings'
jid='marcellus@denmark.lit'
jid='bard@shakespeare.lit'
subid='991d7fd1616fd041015064133cd097a10030819e'>
<x xmlns='jabber:x:data' type='submit'>
<field var='FORM_TYPE' type='hidden'>
@ -5610,12 +5755,12 @@ And by opposing end them?
<iq type='result'
from='pubsub.shakespeare.lit'
to='marcellus@denmark.lit/castle'
to='bard@shakespeare.lit/globe'
id='filter3'/>
]]></example>
<p>The subscriber will then be notified about events that match the keyword.</p>
<example caption='Event notification for matched keyword'><![CDATA[
<message from='pubsub.shakespeare.lit' to='marcellus@denmark.lit'>
<message from='pubsub.shakespeare.lit' to='bard@shakespeare.lit'>
<event xmlns='http://jabber.org/protocol/pubsub#event'>
<items node='princely_musings'>
<item id='4e30f35051b7b8b42abe083742187228'>