[This local archive copy is from the official and canonical URL, http://www.w3.org/TR/1998/NOTE-ice-19981026; please refer to the canonical source document if possible.]
This document is a submission to the World Wide Web Consortium (see Submission Request, W3C Staff Comment). It is intended for review and comment by W3C members and other interested parties.
This document is a NOTE made available by the W3 Consortium for discussion only. This indicates no endorsement of its content, nor that the Consortium has, is, or will be allocating any resources to the issues addressed by this NOTE.
This document describes the Information and Content Exchange protocol for use by content syndicators and their subscribers. The ICE protocol defines the roles and responsibilities of syndicators and subscribers, defines the format and method of content exchange, and provides support for management and control of syndication relationships. We expect ICE to be useful in automating content exchange and reuse, both in traditional publishing contexts and in business-to-business relationships.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
In the HTML version of this specification, those key words are CAPITALIZED BOLD. Capitalization is significant; uncapitalized uses of the key words are intended to be interpreted in their normal, informal, English language way. Bold face is not significant, and is used to aid comprehension, but the bold font is non-normative and the absence of a bold font MUST NOT be given any semantic interpretation.
Reusing and redistributing information and content from one web site to another is an ad hoc and expensive process. The expense derives from two different types of problem:
Successful content syndication requires solving both halves of this puzzle. Fortunately, industry specific efforts already exist for solving the vocabulary problems. For example, Ontology.org (http://www.ontology.org) is an organization devoted to fostering development of industry specific XML DTDs. Other examples of this type of effort include HL7 for the health care industry, or recent W3C XML efforts for mathematics. Although many industries have yet to establish efforts in this area, more will do so as XML and the Web continue to create opportunities for economic gain via on-line applications.
ICE completes the picture by providing the solution for the other half of the puzzle. Specifically, ICE manages and automates establishment of syndication relationships, data transfer, and results analysis. When combined with an industry-specific vocabulary, ICE provides a complete solution for syndicating any type of information between information providers and their subscribers.
The authoring group defined a number of design goals for ICE based on requirements analysis and much thought and discussion. Some of the most important design goals for ICE are included here for reference:
Note: These goals are non-normative. They are included here for historical purposes only.
Many other standards describe how to transmit data of one form or another between systems. This section briefly discusses some of these protocols and describes their relationship to ICE.
ICE is an application of the Extensible Markup Language (XML). Basic concepts in ICE are represented using the element/attribute markup model of XML. Note, however, that ICE is a protocol, not just a DTD, and so in that way differs fundamentally from other pure-document applications of XML such as MathML (mathematical formula markup language), PGML (Precision Graphics Markup Language), etc.
Channel Definition Format (CDF) specifies the operation of push channels. Like ICE, it defines a mechanism for scheduling delivery of encapsulated content. ICE builds on some of the concepts of CDF, such as delivery schedules. Note that ICE goes well beyond what CDF can do; CDF has no notion of explicit subscription relationship management, asset management, reliable sequenced package delivery, asset repair operations, constraints, etc.
We expect ICE will be useful for server-to-server syndication to distribute and/or aggregate content to/from various push servers, whereas CDF is useful for server-to-browser applications.
The Open Software Description (OSD) Format automates distribution of software packages. OSD focuses on concepts such as package dependencies, OS requirements, environmental requirements (such as: how much disk space does a software package require), etc. ICE has very little overlap or relationship to OSD.
We expect ICE to be useful for server-to-server syndication to distribute and/or aggregate content to/from one OSD server to another, whereas OSD continues to be useful for its intended domain of distributing and installing software directly to target desktop and workgroup server machines.
Quoting from [P3P-arch]: The Platform for Privacy Preferences (P3P) protocol addresses the twin goals of meeting the data privacy expectations of consumers on the Web while assuring that the medium remains available and productive for electronic commerce. When ICE is being used to share user profile information from one business to another, it is the responsibility of the applications on both sides of such a relationship to enforce the appropriate privacy policies in accord with the principles described in P3P, as well as in accord with any governing laws. ICE is merely the transport mechanism for those profiles and is not involved in the enforcement of user profile privacy principles.
Quoting from [WebDAV]: WebDAV (Distributed Authoring and Versioning) specifies a set of methods, headers, and content-types ancillary to HTTP/1.1 for the management of resource properties, creation and management of resource collections, namespace manipulation, and resource locking (collision avoidance).
WebDAV addresses a collaborative authoring environment and has very little overlap with ICE.
Quoting from [NOTE-DRP]: The HTTP Distribution and Replication Protocol was designed to efficiently replicate a hierarchical set of files to a large number of clients. No assumption is made about the content or type of the files; they are simply files in some hierarchical organization.
DRP focuses on the differential-update of information organized as a hierarchy of files. As such, it could be used to solve a portion of the data transfer problems addressed by ICE, but only for those content syndication situations that are file-centric. ICE solves a more general problem of asset exchange, where assets may not necessarily be files in a hierarchy. ICE also addresses explicit subscription relationship management, asset management, reliable sequenced package delivery, asset repair operations, constraints, etc. whereas DRP addresses none of those.
These definitions are used throughout this document. Readers will most likely not fully understand these definitions without also reading through the specification.
The Authoring Group went through several major topics of discussion while designing ICE, and some of the decisions reached are of sufficient interest to warrant recording the thought processes that led to them.
The ICE Authoring Group searched for an existing schema and constraint definition language that would meet the ICE requirements. As an example of these requirements, consider banner ads. A desirable constraint mechanism could represent the rule "banner ads are GIFs and are no larger than X pixels by Y pixels." None of the existing or planned schema and constraint languages can express the "ad banner" constraint.
The ICE Authoring Group felt strongly that:
Therefore, ICE V1.0 defines a constraint reference and transport mechanism, and does not define an actual constraint language. Specifically, this means:
This approach allows constraints to be specified and managed by ICE, without regard to a specific constraint implementation. Indeed, the Authoring Group concluded that having the constraint mechanism defined separately from the transport protocol had additional value in that it provided a natural and flexible way to accommodate a variety of constraint languages, which might develop to address industry-specific requirements.
The Authoring Group intends to go one step further and define an interim constraint language, tentatively named ICE-Constraints. The ICE-Constraints language will suffice to meet the basic requirements of content syndicators and their subscribers, while allowing time for general and more complete solutions to develop. We expect the ICE-Constraints language will also be a useful source of requirements for future general-purpose constraint language designers.
Note that a conforming ICE implementation need not implement any constraint processing at all; like DTD validation and a number of other ICE features, constraint processing is entirely a quality of implementation issue. Its presence or absence has no effect whatsoever on the interoperability of two ICE implementations, because nothing in the protocol state machine flow depends on constraint processing.
This specification uses DTD syntax to define the format of the ICE protocol. The question of why this was done occasionally comes up, given that XML allows for DTDs but does not require them, and given that there are a number of other mechanisms (XML-Data, XSchema, DCD etc.) for defining XML document structure.
Inherently, because ICE is built using well-formed XML documents,
many different methods could have been used to specify syntax.
For example, BNF can be used to define the protocol format as
a grammar, complete with '<'
and '/>'
as literal elements in the productions. The authors of CDF in
fact did this (albeit probably for historical reasons).
The use of a DTD mechanism implies very little about interoperability among implementations and about the ability to use other mechanisms in the future. The important question to ask is: what is the format of the pattern of bits exchanged over the wire. Whether specified using a DTD, XML-Data, BNF, a lex/yacc grammar, or lisp program, the "instance" (pattern of bits in the ICE document) is the same. This is the important point.
There are two places where a DTD is implied. One is in the following requirements:
Note, however, that "validation" could in principle be implemented in a variety of ways. A Receiver MAY use any alternate representation of ICE syntax, and perform some alternate form of validation against that representation, as long as the results are AS-IF the governing ICE DTD had been used.
The second place where a DTD is implied is in the DOCTYPE declaration of an ICE packet. A Receiver MAY simply ignore this declaration if the Receiver is not using a DTD. A Sender MUST supply this declaration, but this presents no particular burden to Sender implementations that function without DTDs; they can simply point to a publicly available known ICE DTD for the purposes of meeting this requirement.
One of the requirements identified early in the design process for ICE was to design a protocol that was transport-independent, so that the concepts and development work done for ICE can be leveraged in a variety of situations. Therefore, the ICE protocol has been designed based on the concept of XML document exchange: each protocol message consists of a valid XML document, and the protocol involves sending such documents back and forth between syndicator and subscriber.
This specification explicitly discusses the binding of the generic ICE protocol to the HTTP transport mechanism. This specification uses the term ICE/HTTP where necessary to specifically refer to the concept of ICE bound to an HTTP transport mechanism.
To preserve the goal of being transport independent, and also to enable ICE to operate within existing network infrastructures, ICE/HTTP transmits payloads using the HTTP POST/Response mechanism. ICE/HTTP does not define any new HTTP headers or modify the HTTP protocol in any way; rather, the entire ICE request/response exchange is contained in the body of the HTTP POST and its associated HTTP Response.
The ICE protocol itself deliberately does not address security, because the required levels of security can be achieved via existing and emerging Internet/Web security mechanisms.
In the specific case of digital signatures, non-repudiation, and similar concepts, two things have happened that have steered the Authoring Group away from the notion of having digital signatures inside ICE itself:
Independent of any future XML digital signing standards, ICE implementations can achieve necessary security using a variety of methods, including:
Also, for interoperability, syndicators and subscribers need to agree on how they will negotiate the security parameters for a given relationship. This is done outside of ICE; e.g., by an agreement to use SSL at a certain level of encryption, etc.
Few internationalization issues occur at the protocol level at which ICE operates, but four specific issues are worthy of note:
ice-code
(see 3.3)
include both a numeric error code and a short phrase,
such as "OK" or "Not found". As is described in detail in 3.3.4,
the phrase is intended for informational purposes only; it
is the numeric error code itself that defines the semantics of the
error message. Internationalized implementations of ICE are expected
to convert the numeric ICE error code into an appropriate
presentation string in the local language. Thus, there
is no requirement for ICE to support multi-lingual versions
of the error code phrase, such as "Mahalo" instead of "OK"
in the 200 code.
ice-sender
(see 3.5.1) encodes the sender's
role as either "subscriber" or "syndicator". These textual strings
are intended as arbitrary tokens representing a specific concept;
they are not intended for presentation and thus have no impact
on internationalization issues.
ice-business-term
element (see 4.3.1). ICE provides
a lang
attribute in all places where human-readable text
is being transported and might require an identification of its specific
language encoding. When used, the lang
attribute SHOULD
be filled in according to standards RFC-1766 (Tags for the
Identification of Languages) and ISO-639 (Code for the representation
of names of languages).
The remainder of this document is organized as follows:
Two entities are involved in forming a business relationship where ICE is used. The Syndicator produces content that is consumed by Subscribers. The Syndicator produces a subscription offer from input from various departments in an organization. Decisions are made about how to make these goods available to prospects. The subscription offer includes terms such as delivery policy, usage reporting, presentation constraints, etc. An organization's sales team engages prospects and reaches a business agreement typically involving legal or contract departments. Once the legal and contractual discussions are concluded, the technical team is provided with the subscription offer details and information regarding the Subscriber. The subscription offer is expressed in terms that a web application can manage (this could be database records, an XML file, a plain text file, and so on). In addition, the technical team may have to set up an account for the subscriber entity, so that the web site can identify who it is accessing the syndication application.
The Subscriber receives the information regarding their account (their subscriber identification and location to request their catalog) and how to obtain a catalog of subscription offers. At this point actual ICE operation can begin. The important point to understand is that ICE starts after the two parties have already agreed to have a relationship, and have already worked out the contractual, monetary, and business implications of that relationship.
The ICE protocol covers four general types of operations:
From the ICE perspective, a relationship between a Syndicator and a Subscriber starts off with some form of Subscription Establishment. In ICE, the subscriber typically begins by obtaining a catalog of possible subscriptions (really, subscription offers) from the Syndicator. The Subscriber then subscribes to particular subscriptions, possibly engaging in protocol parameter negotiation to arrive at mutually agreeable delivery methods and schedules.
The relationship then moves on to the steady state, where the primary message exchanges center on data delivery. ICE uses a package concept as a container mechanism for generic data items. ICE defines a sequenced package model allowing syndicators to support both incremental and full update models. ICE also defines push and pull data transfer models.
Managing exceptional conditions and being able to diagnose problems is an important part of syndication management; accordingly, ICE defines a mechanism by which event logs can be automatically exchanged between (consenting) Subscribers and Syndicators.
Finally, ICE provides a number of mechanisms for supporting miscellaneous operations, such as the ability to renegotiate protocol parameters in an established relationship, the ability to send unsolicited ad-hoc notifications (i.e., textual messages) between systems (presumably ultimately targeted at administrators), the ability to query and ascertain the state of the relationship, etc.
Two simple scenarios are used throughout this specification as the source for examples: syndication of news headlines from an online publisher to other online services, and syndication of a parts catalog from a manufacturer to its distributors.
An online content provider, Headlines.com, allows other online sites to subscribe to their headline service. Headlines.com updates headlines three times a day during weekdays, and once each on Saturday and Sunday. A headline consists of four fields: the headline text, a small thumbnail GIF image, a date, and a URL link that points back to the main story on Headlines.com.
Subscribers who sign up for the headline service can collect these headlines and use them on their own site. They display the headlines on their own site, with the URL links pointing back to Headlines.com. For an extra fee, subscribers may harvest the actual story bodies from Headlines.com and thus keep the traffic on their own site instead of linking back to Headlines.com.
A jet-powered pencil sharpener manufacturer, JetSharp.com, wants to keep its distributors up-to-date with the latest parts and optional accessories catalog at all times. It is very important to JetSharp that its distributors always have easy access to the latest service bulletins, and also that they have the latest information about optional accessories and the corresponding price lists.
Each item in the JetSharp parts catalog consists of some structured data, such as price, shipping weight, and size, and also contains unstructured data consisting of a set of HTML files and GIF images describing the product.
The JetSharp catalog is huge, but, fortunately, changes fairly slowly over time.
The ICE protocol is a request/reply protocol that allows for fully symmetric implementations, where both the Syndicator and Subscriber can initiate requests, and also allowing for a Minimal Subscriber implementation where only the Subscriber can initiate requests (i.e., no agent that would be considered a "server" resides on the Subscriber machine).
There are several key concepts that form the foundation of the ICE protocol. They are introduced here, without regard to their spelling (i.e., how they appear in the protocol). The next chapter (3.0 Protocol Infrastructure) revisits these concepts, and more, with a complete description of the protocol format. But first it is important to understand the basic concepts.
ICE uses payload exchange as its fundamental protocol model, where a payload is defined for the purposes of this specification to be a single instance of an XML document formatted according to the ICE protocol definition. The word payload was chosen simply because it is unusual and does not occur in ordinary casual writing; therefore, it can be carefully and unambiguously used throughout a specification.
Payloads can contain requests, responses or unsolicited messages. The unsolicited messages are used to support Minimal Subscriber implementations and will be explained in that context, later (see 2.2.4). A request is a message asking for the performance of an operation, and a payload is used to transmit the request. For example, when a Subscriber wishes to initiate a relationship by obtaining a catalog from a Syndicator, the Subscriber sends the Syndicator a payload containing a "get catalog" request. Similarly, a response is a message containing the results of an operation and a payload is also used to transmit responses.
Every logical operation in ICE is described by a request/response pair. All operations are forced to fit this model; thus, a valid ICE protocol session always comprises an even number of messages when it is in the idle state (i.e., there is a matching response for every request).
There are a few operations in ICE that have no logical requirement for a response. Nevertheless, to preserve the nature of the request/response protocol, responses are returned anyway.
The Subscriber and Syndicator assume several different roles during ICE protocol operations: Subscriber vs. Syndicator, Requestor vs. Responder, and Sender vs. Receiver.
The definition of Subscriber and Syndicator is based on the business relationships: the Syndicator distributes content to the Subscriber. These terms are capitalized throughout this specification wherever they refer specifically to the roles of the parties in an ICE relationship, as opposed to the general concepts of subscribing and syndicating.
The definition of Requestor/Responder is based on who initiates the ICE operation. The initiator is the Requestor, and the other party, who performs the operation, is the Responder. It is possible for a Syndicator to be either a Requestor or a Responder, depending on the particular operation. The same is true for a Subscriber. For example, when a Subscriber initiates a "get catalog" request to a Syndicator, the Subscriber is the Requestor. When a Syndicator initiates a "push package update" request to a Subscriber, the Syndicator is the Requestor.
Finally, the concept of Sender and Receiver are used in this specification to describe the relationship with respect to the transmission of a single payload. A payload travels from Sender to Receiver (and this thus forms the definition of Sender and Receiver).
Note that an ICE operation inherently consists of a Request/Response pair. Thus, the Requestor starts out being a Sender, sending a payload, containing a request, to the Receiver. The Receiver of this first payload is the Responder. When the Responder has performed the operation and wishes to return the results, the Responder becomes the Sender of a payload containing the response, and the initial Requester is now the Receiver.
Due to the nature of the content syndication business, it is important for ICE to support Subscriber implementations of varying levels of sophistication. In the most general case, a Subscriber is a sophisticated server implementation capable of not only sending ICE requests, but also receiving communications initiated by the Syndicator at any time, such as the "push" of new content. That is, a "full" Subscriber has an ICE server running at all times. ICE also supports the concept of a Minimal Subscriber implementation. This is a Subscriber that can initiate communicates (e.g. polling for updates) but does not have a persistent server available to receive requests. A Minimal Subscriber is expected to be run on demand, either by a user or by an automated script.
Thus, in a Minimal Subscriber implementation, the Subscriber always initiates any communication, and therefore the Syndicator cannot initiate any communication to the Subscriber. In that case the Subscriber is always the Requestor, and never the Responder. However, sometimes a Syndicator needs to initiate a message to a Subscriber. For example, the Syndicator might wish to send a "notify" message containing warning that the system will be down next week.
To support Minimal Subscribers and yet still allow Syndicators to initiate requests, ICE defines a mechanism called the Unsolicited Message mechanism. This mechanism supports sending ICE requests from a Syndicator to the Subscriber in a protocol communication initiated by the Subscriber.
As will be seen later when unsolicited messages are explained in detail, the unsolicited message mechanism is largely orthogonal to the primary ICE request/response protocol mechanism. It is defined as an additional set of message types that can be carried by payloads, and as such can be understood separately. See section 3.9, Unsolicited Message Operation for more details. For explanatory purposes, most of this specification ignores the implication of the unsolicited message mechanism when explaining how ICE works; section 3.9 then describes in detail how the unsolicited message mechanism interacts with the rest of ICE. It is important to note, however, that support for unsolicited messages is not optional; all ICE Subscribers and Syndicators MUST implement the unsolicited message mechanism as described in this specification.
ICE uses XML document exchange as its fundamental protocol
model. ICE messages are valid XML documents, with a single ice-payload
root element (defined in detail later) and a structured hierarchy
of tags describing the ICE operations and data.
This section describes the specifics of how ICE payload exchange is performed using HTTP.
To send an ICE/HTTP payload, the Sender performs an HTTP POST to a URL provided by the Receiver. ICE does not define the mechanism by which the Sender first obtains this URL; typically it will be communicated during a phone call, e-mail, or contract exchange when the two parties are establishing their initial relationship. It is expected that conventions for this URL will develop over time, in much the same way the convention of "http://www.domain-name" has developed for web sites.
Every ICE logical operation begins with a Sender sending a request; typically this is the Subscriber initiating an operation to the Syndicator. In some cases, such as push delivery of packages, the Syndicator initiates the operation and is the Sender.
As will be shown in detail later, ICE requests are specified
using an ice-request
XML element, and ICE responses
are specified using an ice-response
element. For
ICE/HTTP, the ice-request
MUST be sent in
an HTTP POST, and the ice-response
to that request
MUST be sent in the HTTP Response to that POST. Thus, a
single ICE request/response pair always maps directly to a single
HTTP POST/Response pair.
Operations involving package transmission can ask for an additional
confirmation, i.e., a third message (request/response/confirmation).
In that case the confirmation message is actually a separate request
with its own response, so the physical realization of (request/response/confirmation)
is actually (request/response/request/response). This will be
explained in more detail in the confirmation section, for now
it suffices to understand that a confirmation message is simply
POSTed as another ice-request
.
An example will help illustrate this. Consider package update: the Subscriber makes a "get package" request to the Syndicator, the Syndicator sends a "package" response, and if the Syndicator asks for confirmation then the Subscriber sends a second "confirmation" request.. In a pseudo-code representation of the protocol, the exchanges look like this: (this is pseudo-code, it does not represent the actual protocol format):
(1) SUBSCRIBER ==> SYNDICATOR: HTTP POST: <ice-payload> <ice-request> Get Package </ice-request> </ice-payload> (2) SUBSCRIBER <== SYNDICATOR: HTTP Response to the POST: <ice-payload> <ice-response> Package: X Confirmation Required </ice-response> </ice-payload>
Note that this exchange of an ice-request
and
an ice-response
occurs entirely within a single HTTP
POST/Response transport level transaction.
(3) SUBSCRIBER ==> SYNDICATOR: HTTP POST: <ice-payload> <ice-request> Confirmation of Package X </ice-request> </ice-payload> (4) SUBSCRIBER <== SYNDICATOR: HTTP Response to the POST: <ice-payload> <ice-response> </ice-response> </ice-payload>
A confirmation message is a request that (logically) needs no response, other than the "ack" necessary to maintain the request/response nature of the ICE protocol.
ICE allows multiple requests or responses to be sent in a single
ice-payload
. This allows round-trips to be minimized
whenever possible. For example, a Subscriber with ten subscriptions
to a single Syndicator can send all ten "get package"
requests and receive all ten updates in a single HTTP POST/Response
communication.
Four key restrictions about the multiple request/response model must be clearly understood:
ice-request
elements in a single
ice-payload
does not imply any ordering or transactional
semantics. A Sender MUST assume the Receiver processes
the requests in an arbitrary order, AS-IF each request had been
sent separately in its own payload.
ice-request
elements
and ice-response
elements within a single ice-payload
.
ice-response
elements in a response
payload MUST be the same as the number of ice-request
elements in the initiating payload, with the sole exception to
this rule being errors and conditions related to the entire payload,
as explained in the discussion of 3xx Payload-Level Status Codes
in section 3.3.4 (Defined Status Codes).
ice-response
element in a response payload
MUST be a response to an ice-request
element
in the initiating payload.
Package update responses can potentially be quite large; the
above rules provide no relief from the possibility that asking
for ten package updates would result in a response that is 900MB
in length (or longer). This problem can be called the Huge
Response problem. ICE provides Syndicators with two mechanisms
by which they can avoid causing the Huge Response problem: the
use of external XML entities and/or the use of an ice-item-ref
mechanism for transmitting package content external to the actual
response. Whether or not a Syndicator chooses to use these mechanisms
(and thus avoid causing the Huge Response problem) is a quality
of implementation issue.
  | Informational Note |
  | for historical reference |
  |
As already noted, a single A more general model would allow arbitrary packing and piggybacking of requests and responses into the HTTP POST/Response stream. This design was explicitly rejected because it imposes complexity on ICE implementations and makes it impossible to implement simple programs that create ICE/HTTP connections and perform simple operations. To see why this is so, consider an "ICE Ping" utility:
If arbitrary piggybacking were permitted, the Ping utility might get a 900MB package pushed at it when all it was expecting was a simple reply. The implication of the arbitrary piggybacking model on implementations is profound: all communication would have to be mediated through a message queue multiplexor/demultiplexor agent that can appropriately dispatch any piggybacked messages. In such an environment it becomes impossible to simply write a perl script (for example) that creates a direct HTTP connection, sends a preformatted packet, and simply prints the response. The restrictions on requests and responses in single payloads in ICE were chosen to avoid this complexity. The ability to create simple implementations was considered more compelling than the ability to further optimize HTTP communication via arbitrary piggybacking. |
When ICE payloads are transmitted via HTTP, the Content-Type MUST be application/x-ice.
This section describes aspects of the ICE protocol that are common across all types of operations, whereas later sections of the document describe the specific operations themselves.
ICE uses XML as the format for its payloads, and all ICE payloads MUST be formatted in accordance with the XML 1.0 specification [W3C-WD-xml]. Furthermore, ICE payloads MUST be well-formed and MUST be valid according to the ICE DTD.
This document does not repeat the general rules for proper XML encoding; readers are expected to refer to the XML specification.
ICE makes extensive use of XML attributes for representing values. The following requirements apply to the interpretation of attribute values:
"equivalent" |
" equivalent " |
ICE uses globally unique identifiers for identifying Subscribers and Syndicators. The globally unique identifier for the Subscriber and Syndicator MUST conform to the Universal Unique Identifier defined by the Open Group [OG-UUID]. Note that if a given installation sometimes functions as a Subscriber and sometimes functions as a Syndicator then it MAY use the same UUID as its identification in both roles.
The UUID format as specified consists of 32 hexadecimal digits, with optional embedded hyphen characters. Per the requirements in the Universal Unique Identifier specification, ICE implementations MUST ignore all hyphens when comparing UUID values for equality, regardless of where the hyphens occur. Also, note that comparisons MUST be case insensitive.
Aside from the Subscriber UUID and the Syndicator UUID, no other identifiers required by ICE are defined by the ICE protocol. All other identifiers function as being unique only within a certain scope. For example, a subscription identifier is generated by a Syndicator when the relationship between a Subscriber and a Syndicator is first established. The identification string used for the subscription ID need only be unique within the domain of all subscription identifiers generated by that Syndicator.
This section describes the date and time format used by ICE in all contexts where a parseable date is required. The format shown here is a selected profile of options from ISO8601:1988 (with Technical Corrigendum 1 applied), hereinafter referred to as [ISO8601].
The format for a date string in ICE Date Format is:
CCYY-MM-DD
where CCYY
is the four-digit year (century and
year, as described in [ISO8601]), MM
is a two-digit
month number, DD
is the two-digit ordinal number
of the day within the calendar month, and the separator character
is a "-
" (hyphen). This format is the Extended
Format described in [ISO8601] section 5.2.1.1, with the separator
as described in [ISO8601] section 4.4, and ICE implementations
MUST use this format for all date strings specified as
being in ICE Date Format.
Note that specifying a Date without a time rarely makes sense; see 3.2.5 for how to specify both.
The format for a time string in ICE Time Format is:
hh:mm:ss
where hh
is the two-digit hour in 24 hour notation
ranging from 00 to 24 (this is not a typo), mm
is
the two-digit minute ranging from 00 to 59, ss
is
the two-digit seconds ranging from 00 to 59, and the separator
character is a ":
" (colon). This format
is the Extended Format described in [ISO8601] section 5.3.1.1,
with the separator as described in [ISO8601] section 4.4, and
ICE implementations MUST use this format for all time strings
specified as being in ICE Time Format.
Note that midnight has two representations:
00:00:00 24:00:00
This is deliberate, and in accordance with [ISO8601] section 5.3.2.
ICE Time Format for representing subsecond granularity follows
[ISO8601] section 5.3.1.3, and thus uses a ",
"
(comma) separator and an arbitrary number of digits representing
the fraction down to whatever level of precision is appropriate.
Thus, the format for time with subsecond resolution is:
hh:mm:ss,s
where the ",
" (comma) is a literal character
([ISO8601] separator) and s
after the comma is "to
the right of the decimal mark" and indicates the subsecond
value. The number of digits in the subsecond value, and the precision
of the subsecond value, and the ability of a given implementation
to honor that precision, are quality of implementation issues
and are not specified by ICE. Implementations MUST properly
parse subsecond values up to at least 9 digits. Note that this
does not imply the ability to actually resolve time down to the
nanosecond; it merely implies the ability to read such a timestamp
and then process it as best as the implementation can. Implementations
SHOULD properly parse fractions with an arbitrary number
of digits in the subsecond value.
All times specified within ICE MUST be specified using GMT (UTC). Implementations are expected to translate these times into the appropriate local time presentation format before interacting with users.
When a Date and Time need to be specified in a single string, the ICE Date and Time format is:
CCYY-MM-DDThh:mm:ss,s
where "T
" (upper case letter T) is a
literal character ([ISO8601] designator). This format is the Extended
Format of calendar date and time of day as described in
[ISO8601] section 5.4.1 clause (a).
Senders MUST NOT specify invalid combinations of fields, such as February 31. Receivers SHOULD reject invalid combinations of fields, rather than trying to interpret them.
When a period of time needs to be specified, the ICE Duration format is:
PnS
where the "P" (upper case letter P) is a literal character ([ISO8601] designator), "n" is an arbitrarily large integer value, and "S" (upper case letter S) is a literal character. This format denotes a number of seconds. It is a specific profile of the choices available in [ISO8601] section 5.5.3.2; note that the alternative format restrictions (5.5.3.2.1) are not used by ICE. Implementations are expected to translate this representation into a more appropriate form before interacting with users.
To describe a period of time with subsecond granularity, the format is:
Pn,nS
i.e., using the same subsecond granularity syntax as described in 3.2.3 above.
All periods of time described as being in ICE Duration Format
in ICE MUST be specified in either the PnS
or Pn,nS
format.
Note that long periods of time are represented by large quantities
of seconds in the above formats. For example, a period of one
day is P86400S
. It is expected that implementations
will translate these time periods into a more familiar form as
part of their user interfaces.
ICE uses the familiar Internet protocol paradigm of three-digit status values in responses to protocol operations. This paradigm was chosen because it is well understood and is suited to both machine-to-machine communication and human interpretation.
There is no relationship between the status codes in ICE and the status codes at the HTTP transport level. As already described above, HTTP is merely the transport mechanism for ICE payloads, and any ICE implementation MUST appropriately handle HTTP status or error conditions at the transport level. For example, if a Subscriber encounters an HTTP-level redirect (3XX code), the Subscriber MUST honor it. The semantics of completing the HTTP transport operation do not affect the semantics of the ICE operations, as defined by the exchange of payloads, in any way.
Throughout the rest of this discussion, an HTTP status of "200 OK" is implicit for the transport of the ICE payloads.
The format of status codes is described by the following DTD fragment:
Status Code and Error Code Structure |
<!ELEMENT ice-code (#PCDATA) > <!ATTLIST ice-code numeric CDATA #REQUIRED phrase CDATA #REQUIRED payload-id CDATA #IMPLIED message-id CDATA #IMPLIED package-id CDATA #IMPLIED lang CDATA #IMPLIED > |
and an example would be:
<ice-code numeric="402" phrase="Not well formed XML" message-id="1998-07-01T11:34:10@nr3.com-1" > Your XML contained overlapping elements. Here is the offending fragment: <a><b>cdefg</a></b> </ice-code>
The attributes are:
payload-id
of the payload referenced by this code. A Sender SHOULD
supply this when reporting a payload-level (3xx) code, and MUST
NOT supply it any other time. See further discussion of payload
errors.
request-id
of the request referenced by this code, or, in some cases, the
response-id
of the response referenced by this code.
A Sender MUST supply this in all cases except when reporting
a payload-level (3xx) code.
package-id
of the package referenced by this code. A Sender MUST
supply this when issuing a confirmation or a surprise code (see 3.7)
that refers to a package.
ice-code
.
The body of the ice-code
element is free-form
text (#PCDATA
) and can be used by implementations
to report human-readable descriptions. It has no semantics in
ICE.
Implementation note: it is very important to properly escape
any fragments reported in the body of the ice-code
.
See, for example, the example shown in 3.3.2. Note in particular
that XML and HTML (and, more generally, any text containing angle
brackets and other syntactically significant characters) must be
properly escaped.
The defined status codes are shown below. Each bullet item
contains the three-digit numeric
value, the corresponding
phrase
, and a description in italics. Note that the
description in italics is part of the explanation and not part
of the status message.
When generating codes:
numeric
value from the set defined here.
phrase
field
(enforced by the DTD).
phrase
shown
in the list below.
When receiving codes:
phrase
data
for any purpose other than as informational data with no defined
semantics. A typical use for the text string is to display it
on a console, or put it into a log file for later analysis by
humans.
ice-code
element for any purpose other than as informational data with
no defined semantics.
The status values defined by ICE are:
2xx: Success
3xx: Payload-level Status Codes
These indicate something about the ice-payload
itself, as opposed to the individual requests and responses within
the payload. These codes have one very explicit and important
semantic: they are used when the payload could not be properly
interpreted, meaning that even if there were multiple requests
in the payload, there will be only one ice-code
in
the response. For example, if the payload had been corrupted,
it might be so corrupted that it isn't even possible to determine
how many requests it contains, let alone respond to them individually.
The specific codes are:
4xx: Request-level Status Codes
These indicate errors caused by an inability to carry out an individual request. Note that in some cases there are similar errors between the 3xx and 4xx class; the difference is whether or not the error is supplied as a single, payload-level error code (3xx) or whether it is supplied as a per-request code.
5xx: Implementation errors and operational failures
These indicate errors caused by internal or operational problems, rather than by incorrect requests. Note that, like all other codes except for the 3xx series, these must be sent individually with each response; if the error condition or operational problem prevents the Responder from resolving the original payload down to the request level, use a 3xx code instead.
6xx: Pending State
These codes indicate a state condition where the Subscriber is expected to send something to the Syndicator, or vice-versa.
ice-unsolicited-now
but the Syndicator has
no unsolicited messages to send.
7xx: Local Use Codes
These codes are reserved for use by the local ICE implementation
and MUST NOT ever be sent over the wire. The intent is
that this range of codes can be used by the local ICE implementation
software to communicate transport-level error conditions, or other
specific local conditions, using the ice-code
mechanism
in a way guaranteed to not collide with any other usage of ice-code
values.
9xx: Experimental Codes
ICE implementations MUST NOT use any codes not listed in this specification, unless those codes are in the 9xx range. The 9xx range allows implementations to experiment with new codes and new facilities without fear of collision with future versions of ICE.
How a given system treats any 9xx code is a quality of implementation issue.
Two special codes have been defined explicitly to support the concept of redirection at the ICE level: 390 for temporary redirection, and 391 for permanent redirection.
When performing a redirection, the Responder sends the appropriate
ice-code
and an ice-location
structure,
shown here:
ICE location element |
<!ELEMENT ice-location EMPTY> <!ATTLIST ice-location target CDATA #REQUIRED > |
The target
attribute MUST be filled in
with the correct new transport communication endpoint. In ICE/HTTP,
this means that target
is filled in with a new URL.
Redirection applies at the payload level, and not individually to the requests within the payload.
Each message in ICE is encapsulated in a single top-level structure
known as an ice-payload
, or just "payload"
for short. This payload is a well-formed XML document that is
also valid according to the ICE DTD.
ICE messages MUST begin with a suitable XML document type declaration such as:
<?xml version="1.0"?> <!DOCTYPE ice-payload SYSTEM "http://www.iceag.org/ICE.dtd" [ ] >
Any alternate form of the above declaration is acceptable; the requirement is simply that a DTD MUST be specified somehow.
This declares the message to be valid XML according to the supplied DTD. The specific URL MUST be a functional URL that will return the DTD defining the version of the ICE protocol used to create this message.
The root node of the payload is the ice-payload
element as shown here:
Payload structure |
<!ELEMENT ice-payload (ice-header, (ice-request+ | ice-response+ | ice-unsolicited-now | ice-unsolicited-request+ | ice-unsolicited-response+ ) ) > <!ATTLIST ice-payload payload-id CDATA #REQUIRED timestamp CDATA #REQUIRED ice.version CDATA #REQUIRED > |
A single ICE payload contains a header and either:
ice-request
elements, or
ice-response
elements, or
ice-unsolicited-now
element, or
ice-unsolicited-request
elements,
or
ice-unsolicited-response
elements
Note that payloads are homogeneous, in the sense that elements
from the above list MUST NOT be mixed together in a single
payload. For example, a single payload can contain multiple ice-request
elements, but it cannot contain ice-request
elements
and ice-response
elements. The DTD representation
shown above enforces this constraint.
The semantics of the unsolicited elements are described in section 3.9 and will not be discussed further until then.
There are several attributes:
ice-payload
element. It provides a handle for error reporting and traffic
monitoring. This id is assigned by the Sender and MUST
be unique across all ICE payloads that a Sender sends to a particular
Receiver. ICE does not define the format of this identifier in
any way.
ice-payload
element
and is provided for debugging and analysis purposes only. It
MUST be formatted according to the ICE DateTime format
with full resolution down to the seconds; it SHOULD be
formatted with finer resolution if possible.
  | Informational Note |
  | for historical reference |
  | The ICE Authoring Group wishes to acknowledge the authors of the XML specification, from whom we copied (and adapted) our description of the semantics of the ice.version attribute. |
The ice-header
is common among all ICE payloads
and contains a consistent structure for both syndicators and subscribers.
The following DTD fragment describes the header structure. The
basic data captured in the ice-header
element is
the Sender identification. The Sender of the ICE message can either
be a syndicator or a subscriber.
Header structure |
<!ELEMENT ice-header (ice-sender, ice-receiver? , ice-user-agent? ) > |
<!ELEMENT ice-sender EMPTY > <!ATTLIST ice-sender sender-id CDATA #REQUIRED name CDATA #REQUIRED role (subscriber | syndicator) #REQUIRED > |
<!ELEMENT ice-receiver EMPTY > <!ATTLIST ice-receiver receiver-id CDATA #REQUIRED name CDATA #REQUIRED > |
<!ELEMENT ice-user-agent (#PCDATA)> |
The ice-sender
element describes the originator
of the payload. The attribute fields are:
The ice-receiver
element is optional, and describes
the intended target of the payload. It is optional because the
target of the payload presumably already knows this information;
however, some implementations MAY choose to supply this
data as a debugging aid. Note that the element is optional; however,
if the element is supplied the following attributes are REQUIRED:
This field allows ICE tools to identify themselves with an arbitrary string, in a way analogous to the HTTP User-Agent string. Implementations SHOULD supply this string when sending a payload. No semantics for the contents of this string are defined by this specification.
Each ICE payload contains one or more ice-request
elements, or one or more ice-response
elements, or
the unsolicited support elements which are described later in
this document. Note that a Sender MUST NOT mix request
and response elements within a single payload, and a Receiver
SHOULD reject such a payload with a 303 Payload validation
failure error.
ICE requests and responses |
<!ELEMENT ice-request (ice-cancel | ice-change-subscription | ice-code | ice-get-catalog | ice-get-event-log | ice-get-package | ice-get-sequence | ice-get-status | ice-nop | ice-notify | ice-offer | ice-package+ | ice-send-confirmations | ice-repair-item ) > <!ATTLIST ice-request request-id CDATA #REQUIRED > |
<!ELEMENT ice-response (ice-code, (ice-cancellation | ice-catalog | ice-event-log | ice-offer | ice-location | ice-package+ | ice-sequence | ice-status | ice-subscription | )? ) > <!ATTLIST ice-response response-id CDATA #REQUIRED unsolicited-pending (false | true) "false" > |
An ice-request
describes a requested ICE operation.
Other parts of this specification describe the elements representing
the actual ICE operations (ice-cancel
, ice-get-catalog
,
etc); only the attributes of the ice-request
are
described here.
The sole attribute is:
An ice-response
describes a response to a previously
requested ICE operation. Other parts of this specification describe
the elements representing the actual ICE responses (ice-cancellation
,
ice-catalog
, etc.); only the subelements and the
attributes of the ice-response
are described here.
Note that an ice-response
consists of an ice-code
,
containing the code, and an optional additional element chosen
from ice-cancellation
, ice-catalog
,
etc. For this discussion, call those elements "results elements."
Considering the possibility of a successful vs. unsuccessful code
value, and the presence or absence of the results element, there
are four combinations possible:
ice-code
2xx (any success code) and a results
element: This would be a normal, successful, response to an operation
that returned something. For example, the response to an ice-get-catalog
includes an ice-catalog
.
ice-code
2xx (any success code) and no results
element: This would be a normal, successful, response to an operation
that did not return anything and merely needed to indicate acknowledgement.
For example, the response to an ice-notify
operation
contains no additional data, and so none is sent.
ice-code
XXX (any error code) and a results
element: This is used in certain specific cases to communicate
additional data with an error response. For example, in response
to an ice-subscribe
request, the response might
be error code 441 (Counter-proposal) and an ice-offer
.
ice-code
XXX (any error code) and no results
element: This would be a normal, unsuccessful, response to an
operation. The error code, message, reference, and free-form
text is all communicated within the ice-code
element
itself.
There are several attributes:
ice-response
(who, by definition,
was the Receiver of the ice-request
to which this
is a response). This id has the same uniqueness requirements
as the request-id
in an ice-request
.
The complete set of conditions under which an ice-response
will contain a code value other than 200 (OK) and also contain
a results element are given here. In all other cases, a code value
other than 200 will have no results element in the ice-response
.
When ICE transmits a package, it is possible that the Syndicator
might want a separate confirmation that the Subscriber correctly
received and processed all the data. This is especially important
for packages that require resolution (and fetching) of remote
URLs in order to fully resolve their data. The confirmation
flag attribute present in the ice-package
element
provides a method for the Syndicator to indicate it wants the
subscriber to return an additional confirmation message.
More generally, there are times when an implementation might
wish to communicate an explicit processing error at some later
point in time, long after the actual ICE Request/Response message
exchange has completed. Consider the case where a Syndicator pushes
a package to a Subscriber, without a confirmation flag. After
acknowledging the receipt of the bits and returning a 200 (OK)
code, the Subscriber later determines that the package cannot
be processed. Perhaps the XML will not validate, or a remote resource
named in the package could not be fetched. To communicate this
back to the Syndicator, the Subscriber uses a surprise ice-code
.
This is simply an ice-request
where the request contains
an ice-code
. It is called a surprise message
because, unlike the ice-code
field in an ice-response
,
a surprise ice-code
appears asynchronously to any
other state transitions implied by the ICE protocol. To help the
Receiver interpret the surprise message, the message-id
attribute in the ice-code
MUST refer back
to a previous message in the stream, said previous message being
the message that initiated the chain of events leading to the
surprise error. Using a surprise message, either party can send
an ice-request
consisting of an ice-code
letting the other side know that something bad happened. The protocol
dictates that a Receiver respond to a surprise ice-code
with an ice-response
containing an ice-code
and no other elements. Note that the Receiver's ice-code
value merely indicates the usual protocol-level acceptance/rejection
of the message itself; it does not semantically describe anything
about how the Receiver feels about the surprise error. Beyond
defining the response to a surprise error, the protocol does not
define what the Receiver should do upon receipt of such an error
code; at a minimum the most likely implementation will be to bring
the situation to the attention of an administrator.
Explicit confirmation requests in package delivery can then
be seen as a specific variation of this concept. In confirmation,
the Syndicator is explicitly soliciting a future "surprise"
ice-code
message and expects to receive it even if
the result is 200 (OK).
The format of an ice-code
message is simply an
ice-request
containing an ice-code
;
both elements have already been described and will not be described
again here. As an example, here is an ice-code
message
that a Subscriber might send after a package failed to validate:
<ice-request request-id="1998-08-11T12:34:56@xyz.com-1" > <ice-code numeric="403" phrase="Validation failure" message-id="1998-07-01T11:34:10@nr3.com-1" package-id="pkg5519923" > Could not validate the package you sent. </ice-code> </ice-request>
The response packet might look like this:
<ice-response request-id="1998-07-05T02:03:45@nr3.com-1" > <ice-code numeric="200" phrase="OK" message-id="1998-08-11T12:34:56@xyz.com-1" > </ice-code> </ice-response>
Packages can be sent in either an ice-request
or an ice-response
(depending on push/pull mode).
Regardless of how sent, whenever a Subscriber receives packages
with a confirmation
flag with value true
,
the Subscriber MUST eventually send an appropriate ice-code
message as the confirmation. As noted above, the right way to
think of this is that the confirmation ice-code
message
is a surprise ice-code
message, except that in this
case the Syndicator has explicitly solicited it and so the Subscriber
MUST eventually send it.
Package confirmation specifically implies the following:
This is a much stricter set of acknowledgements than that implied by the 200 (OK) response to the package transmission. After a Syndicator receives a confirmation message, it may assume that the package has been fully processed by the Subscriber and that no further error conditions will occur regarding that particular package.
In push subscriptions, a Subscriber will send two different
code messages to the Syndicator if confirmation has been requested.
The first will be the one contained in the ice-response
that the Subscriber will send in response to the (pushed) ice-request
containing the package. That code will describe whether or not
the Subscriber correctly received the push message. Second, sometime
later the Subscriber will send another ice-code
to
describe the higher level results noted above as being part of
confirmation.
Note that the Syndicator can control the level of complexity associated
with the confirmation mechanism. In the simplest implementations, a Syndicator
need never ask for any confirmations. Another simple implementation
would be to ask for confirmations, and never allow a subsequent package
to be delivered until the preceding confirmation is received (effectively
implementing a "stop-and-wait" fully-serial style protocol).
Much more complex implementations, including windowing (allowing
multiple outstanding confirmations) are possible. Note that
the protocol includes two other tools for Syndicators to use in
implementing confirmations: ice-send-confirmations
as a request allowing a Syndicator to poll a Subscriber for outstanding
confirmations (see 5.5.1), and the 602 (Excessive confirmations outstanding)
error code, which allows a Syndicator to force a Subscriber to
synchronize (i.e., to send outstanding confirmations before proceeding
any further). These mechanisms give complete control over
confirmation to the Syndicators, and allow Syndicators to implement many
different models as necessary to meet their requirements.
Two codes have been defined specifically for use with confirmation messages: 201 (Confirmed) and 430 (Not confirmed).
To confirm success, a Sender MUST use the 201 code, not the 200 code. The purpose of this restriction is to emphasize that confirmation is performing a higher-level application oriented check that is different from the ordinary processing implied by 200. For interoperability, a Receiver SHOULD accept either the 200 or 201 code as an acceptable positive confirmation.
To confirm failure, a Sender MUST use an error code. The error code 430 ("Not confirmed") has been set aside for use as a generic "something bad happened" code, but if more details can be accurately conveyed by a different code then the Sender SHOULD use it.
This section shows a complete ICE nop exchange between a Sender and a Receiver, as a way of illustrating the basic ICE protocol principles outlined above.
In this example, the Sender sends a payload containing only one nop request. The Sender initiates the NOP by POSTing the following payload to the Receivers ICE/HTTP URL:
<?xml version="1.0"?> <!DOCTYPE ice-payload SYSTEM "http://www.somestandard.org/ICE.dtd" > <ice-payload payload-id="1998-07-05T02:02:23@xyz.com" timestamp="02:02:23,449" ice.version="1.0"> <ice-header> <ice-sender sender-id="4af37b30-2c35-11d2-be4a-204c4f4f5020" name="XYZ Corporation" role="subscriber"/> <ice-user-agent> Acme Ray Gun ICE System, V0.9beta </ice-user-agent> </ice-header> <ice-request request-id="1998-07-05T02:02:23@xyz.com-1"> <ice-nop/> </ice-request> </ice-payload>
The response would come back in the HTTP Response of the POST, and look like this:
<?xml version="1.0"?> <!DOCTYPE ice-payload SYSTEM "http://www.somestandard.org/ICE.dtd" > <ice-payload payload-id="1998-07-05T02:03:45@nr3.com" timestamp="02:03:45,31416" ice.version="1.0"> <ice-header> <ice-sender sender-id="4a2180c9-9435-d00f-9317-204d974e3410" name="Number Three Corporation" role="syndicator"/> <ice-user-agent> Road Kill Systems ICE Processor, V17 patch 9 </ice-user-agent> </ice-header> <ice-response response-id="1998-07-05T02:03:45@nr3.com-1"> <ice-code numeric="200" phrase="OK" message-id="1998-07-05T02:02:23@xyz.com-1" > </ice-code> </ice-response> </ice-payload>
This example shows a Subscriber sending a payload containing two nop requests, and the Syndicator responding with two responses. Note that the responses to the nops come back in a different order within the payload than the requests, illustrating one possible side-effect of the fact that no ordering is implied by having multiple requests in a single payload.
Request:
<?xml version="1.0"?> <!DOCTYPE ice-payload SYSTEM "http://www.somestandard.org/ICE.dtd" > <ice-payload payload-id="1998-07-05T03:03:34@xyz.com" timestamp="03:03:34,449" ice.version="1.0"> <ice-header> <ice-sender sender-id="4af37b30-2c35-11d2-be4a-204c4f4f5020" name="XYZ Corporation" role="subscriber"/> <ice-user-agent> Acme Ray Gun ICE System, V0.9beta </ice-user-agent> </ice-header> <ice-request request-id="1998-07-05T03:03:34@xyz.com-1"> <ice-nop/> </ice-request> <ice-request request-id="1998-07-05T03:03:34@xyz.com-2"> <ice-nop/> </ice-request> </ice-payload>
Response:
<?xml version="1.0"?> <!DOCTYPE ice-payload SYSTEM "http://www.somestandard.org/ICE.dtd" > <ice-payload payload-id="1998-07-05T03:03:45@nr3.com" timestamp="03:03:45,31416" ice.version="1.0"> <ice-header> <ice-sender sender-id="4a2180c9-9435-d00f-9317-204d974e3410" name="Number Three Corporation" role="syndicator"/> <ice-user-agent> Road Kill Systems ICE Processor, V17 patch 9 </ice-user-agent> </ice-header> <ice-response response-id="1998-07-05T03:03:45@nr3.com-1"> <ice-code numeric="200" phrase="OK" message-id="1998-07-05T03:03:34@xyz.com-2" > </ice-code> </ice-response> <ice-response response-id="1998-07-05T03:03:45@nr3.com-2"> <ice-code numeric="200" phrase="OK" message-id="1998-07-05T03:03:34@xyz.com-1" > </ice-code> </ice-response> </ice-payload>
ICE allows for simple implementations, known as Minimal Subscriber Implementations, to be legal ICE Subscriber implementations. In a Minimal Subscriber Implementation, the Subscriber provides no method for the Syndicator to initiate messages to the Subscriber; all communication initiates at the Subscriber. This model allows for simple Subscribers that have no active agent for receiving messages from the Syndication server.
There are, however, times in ICE where the Syndicator will want to send messages to the Subscriber. If the Subscriber is not a Minimal Subscriber, the Syndicator can simply send those messages the usual way. If the Subscriber is a Minimal Subscriber Implementation, then the unsolicited message handling support of ICE is necessary to allow these "reverse channel" messages to be sent.
The general model is quite simple:
unsolicited-pending
, can be sent in
an ice-response
. Using this flag, a Syndicator can
tell a Subscriber that there are unsolicited messages awaiting
collection.
unsolicited-pending
flag,
a Subscriber issues a special type of payload element, ice-unsolicited-now
,
to open a back channel from the Syndicator back to the Subscriber.
No information is conveyed in this ice-unsolicited-now
request, other than the implicit desire of the Subscriber to
receive any unsolicited messages that are available at this time.
ice-unsolicited-now
with one or more ice-unsolicited-request
messages,
containing the actual unsolicited messages. If the Syndicator
has no unsolicited messages to send, the Syndicator responds
with an ice-code
604 (No more unsolicited messages).
ice-unsolicited-response
payload element.
ice-unsolicited-response
with an ice-response
, ending the conversation.
There is no hard connection between step 1 (reception of the
flag) and step 2 (opening the channel). A Subscriber MAY
wait an arbitrary period of time before issuing the ice-unsolicited-now
,
and MAY in fact send other messages even after receiving
the unsolicited-pending
flag. A Subscriber SHOULD
issue the ice-unsolicited-now
payload as soon as
possible.
A specific error code, 601 ("Unsolicited messages must be processed now"), has been defined as a way for the Syndicator to indicate, at some point, its unwillingness to converse any further until the pending unsolicited messages have been collected by the Subscriber.
There is also no hard connection between step 3 (reception
by the Subscriber of the logical requests) and step 5 (transmission
by the Subscriber of the logical responses). It is very important
to understand that the reverse unsolicited message channel semantics
are AS-IF the Syndicator could have sent the request directly
to the Subscriber using the normal ice-request
and
received the response using the normal ice-response
.
Thus, all of the normal semantics associated with such a Request/Response
sequence pertain. In particular, note that the number of ice-unsolicited-response
elements in the payload sent from Subscriber to Syndicator MUST
correspond to the number of ice-unsolicited-request
elements. This is the analogous requirement to the one stating
that ice-request
and ice-response
elements
must match in number.
The following DTD fragment shows the format of the ice-unsolicited-now
message that a Subscriber sends to a Syndicator when it is ready
to receive unsolicited messages.
Unsolicited now element |
<!ELEMENT ice-unsolicited-now EMPTY> <!ATTLIST ice-unsolicited-now request-id CDATA #REQUIRED > |
When a Subscriber sends this message, the ice-unsolicited-now
element takes the place of the ice-request
element
the Subscriber would send in all other cases. Thus, the attributes
of the ice-unsolicited-now
element are the same as
those of the ice-request
element:
request-id
attribute in an ice-request
.
Note that Syndicators MUST NOT ever send an ice-unsolicited-now
to a Subscriber. This is discussed in more detail under 3.9.5
Asymmetry.
A Subscriber MAY send an ice-unsolicited-now
at any time. The Subscriber is not forced to wait for the unsolicited-pending
flag before it tries an ice-unsolicited-now
. Thus,
it is perfectly legal for a Subscriber to "ping" a Syndicator
with periodic ice-unsolicited-now
messages; whether
this is a good idea or not is a quality of implementation issue.
Upon receiving an ice-unsolicited-now
, a Syndicator
responds either with an ice-response
containing only
a non-success ice-code
, or else responds with an
ice-unsolicited-request
element. The DTD for the
ice-unsolicited-request
element is shown here:
Unsolicited Request |
<!ELEMENT ice-unsolicited-request (ice-change-subscription | ice-code | ice-get-event-log | ice-get-status | ice-nop | ice-notify | ice-package+ | ice-send-confirmations ) > <!ATTLIST ice-unsolicited-request unsolicited-request-id CDATA #REQUIRED> |
When a Syndicator sends this message, the ice-unsolicited-request
element takes the place of the ice-request
element
the Syndicator would have sent to the Subscriber, if the Syndicator
had been able to send it directly (instead of using the unsolicited
message mechanism). Thus, the attributes of the ice-unsolicited-request
element are the same as those of the ice-request
element:
request-id
attribute in an ice-request
.
Note that the set of operations that can be sent this way is a subset of the full set of operations. This is because of the assymetric nature of the unsolicited message support: only Syndicators can use this mechanism to send messages to Subscribers (not vice versa); therefore, the set of legal requests is restricted to those that a Syndicator would send to a Subscriber.
As with ice-request
, any number of ice-unsolicited-request
elements MAY be sent in a single payload. The maximum number
to send is an implementation-specific quality of implementation
policy decision.
Note that Subscribers MUST NOT ever send an ice-unsolicited-request
to a Syndicator. This is discussed in more detail under 3.9.5
Asymmetry.
Upon receiving an ice-unsolicited-request, a Subscriber performs the operation it contains and eventually sends an ice-unsolicited-response to return the results to the Syndicator. The DTD for the ice-unsolicited-response element is shown here:
Unsolicited Response |
<!ELEMENT ice-unsolicited-response (ice-code, (ice-events | ice-status)?)> <!ATTLIST ice-unsolicited-response unsolicited-response-id CDATA #REQUIRED > |
When a Subscriber sends this message, the ice-unsolicited-response
element takes the place of the ice-response
element
the Subscriber would have sent to the Syndicator, if the Syndicator
had been able to make the original request directly instead of
using the unsolicited message mechanism. Thus, the attributes
of the ice-unsolicited-response
element are the same
as those of the ice-response
element, except that
there is no unsolicited-pending
flag:
response-id
attribute in an ice-response
.
However many ice-unsolicited-request
elements
were sent in the originating payload, that same number of ice-unsolicited-response
elements must appear in the response, unless there is a catastrophic
payload-level error.
Note that Syndicators MUST NOT ever send an ice-unsolicited-response
to a Subscriber. This is discussed in more detail under 3.9.5
Asymmetry.
ICE does not permit a "Minimal Syndicator" implementation; said differently, a Syndicator is REQUIRED to be capable of being a Responder, responding to protocol requests initiated by a Subscriber. Therefore, the implementation requirements for the unsolicited message are asymmetric with respect to Syndicator and Subscriber:
unsolicited-pending
flag, sending
the unsolicited-now
payload, etc.
unsolicited-pending
flag, responding to the unsolicited-now
payload,
etc.
unsolicited-now
payload, and
respond with the code 604 (No more unsolicited messages).
Implementation note: the unsolicited message mechanism makes a good fall-back mechanism for Syndicators to use when communication with their non-Minimal Susbcribers fails. The possibility that a Syndicator MAY choose to use the unsolicited message mechanism in this fashion is the primary reason why all Subscribers MUST implement the subscriber-side portion of the unsolicited message protocol, even if the Subscriber is not a Minimal Subscriber Implementation.
  | Informational Note |
  | for historical reference |
  |
The model specified above is an "explicit"
mechanism, where support for the concept of unsolicited messages
has been added at the most fundamental levels of the ICE protocol;
specifically, at a peer level with the concept of An alternative mechanism would have been to
simply define additional requests for unsolicited messages and
"tunnel" them within the existing
It is a fair criticism of the specified (no-tunneling)
design that it explicitly forces extra communication to handle
unsolicited messages. For example, it is not possible for a Subscriber
to request some ICE operation while at the same time request
unsolicited messages. The solution given in this specification
forces the Subscriber to make two separate payloads in that case:
one for the ordinary |
3.9.6 Policy decisions
The Syndicator and Subscriber each have a variety of implementation-specific policy decisions to make regarding unsolicited messages.
On the Subscriber side, the implementation has to decide how
to treat the reception of the unsolicited-pending
flag. The Subscriber MAY choose to immediately issue an
ice-unsolicited-now
, preempting any other planned
communication that Subscriber might have at the time, or the Subscriber
MAY choose to defer the collection of unsolicited messages
until some later point in time.
The Syndicator has to decide how many unsolicited messages
it will queue for a Subscriber, and when to switch from the mode
of simply flagging their existence with unsolicited-pending
,
and instead forcing the Subscriber to collect them. The Syndicator
uses the 601 (Unsolicited messages must be processed now) code
to force the Subscriber to collect the messages.
In this first example, a Subscriber first performs a nop operation to the Syndicator. The response to the nop operation has the unsolicited-pending flag set. The Subscriber then sends an unsolicited-now to collect the unsolicited message(s). The Syndicator sends two ice-notify operations using unsolicited-request, and the Subscriber responds to both using unsolicited-response.
As explained in 3.9.2 Format of unsolicited-now, it
would have been perfectly legal for a Subscriber to send the ice-unsolicited-now
operation without first getting the unsolicited-pending
flag (which shows up in this example on the first nop). The nop
in this example is used simply as a way to demonstrate the use
of the unsolicited-pending
flag by the Syndicator.
(1): SUB ==> SYN: NOP
The Subscriber sends a nop to the Syndicator:
<?xml version="1.0"?> <!DOCTYPE ice-payload SYSTEM "http://www.somestandard.org/ICE.dtd" > <ice-payload payload-id="1998-07-22T02:02:23@xyz.com" timestamp="02:02:23,449" ice.version="1.0"> <ice-header> <ice-sender sender-id="4af37b30-2c35-11d2-be4a-204c4f4f5020" name="XYZ Corporation" role="subscriber"/> <ice-user-agent> Acme Ray Gun ICE System, V0.9beta </ice-user-agent> </ice-header> <ice-request request-id="1998-07-22T02:02:23@xyz.com-1"> <ice-nop/> </ice-request> </ice-payload>
(2) SUB <== SYN: Response w/unsolicited-pending
The Syndicator responds to the nop and sets the unsolicited-pending
flag:
<?xml version="1.0"?> <!DOCTYPE ice-payload SYSTEM "http://www.somestandard.org/ICE.dtd" > <ice-payload payload-id="1998-07-22T02:03:45@nr3.com" timestamp="02:03:45,31416" ice.version="1.0"> <ice-header> <ice-sender sender-id="4a2180c9-9435-d00f-9317-204d974e3410" name="Number Three Corporation" role="syndicator"/> <ice-user-agent> Road Kill Systems ICE Processor, V17 patch 9 </ice-user-agent> </ice-header> <ice-response response-id="1998-07-22T02:03:45@nr3.com-1" unsolicited-pending="true"> <ice-code numeric="200" phrase="OK" message-id="1998-07-22T02:02:23@xyz.com-1" > </ice-code> </ice-response> </ice-payload>
(3) SUB ==> SYN: ice-unsolicited-now
The Subscriber, having seen the unsolicited-pending
flag, eventually sends an ice-unsolicited-now
:
<?xml version="1.0"?> <!DOCTYPE ice-payload SYSTEM "http://www.somestandard.org/ICE.dtd" > <ice-payload payload-id="1998-07-22T02:03:55@xyz.com" timestamp="02:03:55,449" ice.version="1.0"> <ice-header> <ice-sender sender-id="4af37b30-2c35-11d2-be4a-204c4f4f5020" name="XYZ Corporation" role="subscriber"/> <ice-user-agent> Acme Ray Gun ICE System, V0.9beta </ice-user-agent> </ice-header> <ice-unsolicited-now request-id="1998-07-22T02:03:55@xyz.com-1"/> </ice-payload>
(4) SUB <== SYN: Two unsolicited requests
The Syndicator responds by sending two unsolicited requests; in this example both are notify operations containing textual messages.
<?xml version="1.0"?> <!DOCTYPE ice-payload SYSTEM "http://www.somestandard.org/ICE.dtd" > <ice-payload payload-id="1998-07-22T02:04:01@nr3.com" timestamp="02:04:01,31416" ice.version="1.0"> <ice-header> <ice-sender sender-id="4a2180c9-9435-d00f-9317-204d974e3410" name="Number Three Corporation" role="syndicator"/> <ice-user-agent> Road Kill Systems ICE Processor, V17 patch 9 </ice-user-agent> </ice-header> <ice-unsolicited-request unsolicited-request-id="1998-07-22T02:04:01@nr3.com-1"> <ice-notify priority="2"> Our system will be down for maintenance tomorrow </ice-notify> </ice-unsolicited-request> <ice-unsolicited-request unsolicited-request-id="1998-07-22T02:04:01@nr3.com-2"> <ice-notify priority="4"> Our ICE software will be upgraded next month. </ice-notify> </ice-unsolicited-request> </ice-payload>
(5) SUB ==> SYN: Two unsolicited responses
The Subscriber processes the notify operations, which happen to be simple operations that return no data (convenient for this example). The Subscriber sends the results in an unsolicited-response:
<?xml version="1.0"?> <!DOCTYPE ice-payload SYSTEM "http://www.somestandard.org/ICE.dtd" > <ice-payload payload-id="1998-07-22T02:10:19@xyz.com" timestamp="02:10:19,449" ice.version="1.0"> <ice-header> <ice-sender sender-id="4af37b30-2c35-11d2-be4a-204c4f4f5020" name="XYZ Corporation" role="subscriber"/> <ice-user-agent> Acme Ray Gun ICE System, V0.9beta </ice-user-agent> </ice-header> <ice-unsolicited-response unsolicited-response-id="1998-07-22T02:10:19@xyz.com-1"> <ice-code numeric="200" phrase="OK" message-id="1998-07-22T02:04:01@nr3.com-2" > </ice-code> </ice-unsolicited-response> <ice-unsolicited-response unsolicited-response-id="1998-07-22T02:10:19@xyz.com-2"> <ice-code numeric="200" phrase="OK" message-id="1998-07-22T02:04:01@nr3.com-1" > </ice-code> </ice-unsolicited-response> </ice-payload>
(6) SUB <== SYN: Acknowledgements
To preserve the Request/Response symmetry of the protocol,
the Syndicator is required to respond to the ice-unsolicited-response
messages. The responses contain no useful data, except that they
do also serve as a convenient place for the Syndicator to show
that there are more unsolicited messages pending (this might happen
if the Syndicator chose to not send all of them in one giant payload).
<?xml version="1.0"?> <!DOCTYPE ice-payload SYSTEM "http://www.somestandard.org/ICE.dtd" > <ice-payload payload-id="1998-07-22T02:10:25@nr3.com" timestamp="02:10:25,31416" ice.version="1.0"> <ice-header> <ice-sender sender-id="4a2180c9-9435-d00f-9317-204d974e3410" name="Number Three Corporation" role="syndicator"/> <ice-user-agent> Road Kill Systems ICE Processor, V17 patch 9 </ice-user-agent> </ice-header> <ice-response response-id="1998-07-22T02:10:25@nr3.com-1"> <ice-code numeric="200" phrase="OK" message-id="1998-07-22T02:10:19@xyz.com-1" > </ice-code> </ice-response> <ice-response response-id="1998-07-22T02:10:25@nr3.com-2"> <ice-code numeric="200" phrase="OK" message-id="1998-07-22T02:10:19@xyz.com-2" > </ice-code> </ice-response> </ice-payload>
(7) SUB ==> SYN: Another ice-unsolicited-now
To illustrate the error response, the Subscriber (in this example)
sends another unsolicited-now
message, but this time
the Syndicator has no more messages to send.
<?xml version="1.0"?> <!DOCTYPE ice-payload SYSTEM "http://www.somestandard.org/ICE.dtd" > <ice-payload payload-id="1998-07-22T02:23:55@xyz.com" timestamp="02:23:55,449" ice.version="1.0"> <ice-header> <ice-sender sender-id="4af37b30-2c35-11d2-be4a-204c4f4f5020" name="XYZ Corporation" role="subscriber"/> <ice-user-agent> Acme Ray Gun ICE System, V0.9beta </ice-user-agent> </ice-header> <ice-unsolicited-now request-id="1998-07-22T02:23:55@xyz.com-1"/> </ice-payload>
(8) SUB <== SYN: Error response
As mentioned, the Syndicator (in this example) has no more unsolicited messages to send, so it returns this error:
<?xml version="1.0"?> <!DOCTYPE ice-payload SYSTEM "http://www.somestandard.org/ICE.dtd" > <ice-payload payload-id="1998-07-22T02:24:45@nr3.com" timestamp="02:24:45,31416" ice.version="1.0"> <ice-header> <ice-sender sender-id="4a2180c9-9435-d00f-9317-204d974e3410" name="Number Three Corporation" role="syndicator"/> <ice-user-agent> Road Kill Systems ICE Processor, V17 patch 9 </ice-user-agent> </ice-header> <ice-response response-id="1998-07-22T02:24:45@nr3.com-1"> <ice-code numeric="604" phrase="No more unsolicited messages" message-id="1998-07-22T02:23:55@xyz.com-1" > </ice-code> </ice-response> </ice-payload>
This section describes catalogs, and protocol parameter negotiation, which together form the heart of subscription establishment.
Subscription relationships in ICE usually begin with a request by the Subscriber to obtain a catalog of subscription offers from the syndicator. As already described, prior to the Subscriber making this request, the Subscriber and the Syndicator have probably already engaged in real-world discussions regarding licensing terms, payment options, and other considerations. Those happen outside of the ICE protocol. Once the parties agree that they wish to have a relationship, the ICE process begins.
A typical sequence of events is:
The delivery policy determines the times during which packages can be delivered (push) or requested (pull) for a given subscription. A delivery policy defines the start and stop dates during which the delivery policy is valid, and has one or more delivery rules.
Each subscription offer has a single delivery-policy. A delivery-policy has a start date, a stop date, and contains one or more delivery rules. Delivery policies are described by the following DTD fragment:
ice-delivery-policy |
<!ELEMENT ice-delivery-policy (ice-delivery-rule+) > <!ATTLIST ice-delivery-policy startdate CDATA #IMPLIED stopdate CDATA #IMPLIED > |
The attributes are:
The multiple delivery-rules in a delivery-policy are conceptually joined with "OR" (not "AND"). In other words, the valid delivery times are the union of all the times defined by each rule in the delivery policy.
A delivery-rule defines a window of time during which deliveries can be performed. Each delivery-rule can be either a push or pull, can define which years, months, dates and days of the week in which deliveries can be performed, a start and ending time for the update window, the frequency with which updates can be performed, and the count of the number of updates that can be performed.
Delivery rules are defined by the following DTD fragment
ice-delivery-rule |
<!ELEMENT ice-delivery-rule (ice-negotiable*) > <!ATTLIST ice-delivery-rule mode (push | pull) #REQUIRED monthday NMTOKENS #IMPLIED weekday NMTOKENS #IMPLIED startdate CDATA #IMPLIED stopdate CDATA #IMPLIED starttime CDATA #IMPLIED duration CDATA #IMPLIED minfreq CDATA #IMPLIED maxfreq CDATA #IMPLIED mincount CDATA #IMPLIED maxcount CDATA #IMPLIED url CDATA #IMPLIED > |
The ice-negotiable
element is described in 4.2.3.
The attributes are:
push
or pull
. A push
delivery means that the update is initiated by the Syndicator.
A pull
delivery means that the update is initiated
by the Subscriber.
any
or be the special value last
. Any value that is
out of range for the given month is defined to mean that no delivery
happens that month; this rule applies to "31" in February,
for example, and applies to "32" (or any other out-of-range
value) in all months. Multiple values MAY be specified,
separated by ' '
(space) per the XML NMTOKENS
declaration. The value any
means delivery is not
restricted by day of month, and this is equivalent to not specifying
monthday
at all. The value last
means
delivery is restricted to the last day of the month; this is
defined AS-IF the correct choice of 28,29,30, or 31 had been
given for the month in question. The absence of this attribute
implies any
.
any
.
Multiple values MAY be specified, separate by ' '
(space). The special value any
means delivery is
not restricted by the day of the week. The absence of this attribute
implies any
. In accordance with [ISO8601] section
5.2.3, the days are assigned as follows:
ice-delivery-policy
element, but applies
to this specific ice-delivery-rule
element only.
If earlier than the start date in the containing ice-delivery-policy
,
implementations MUST act AS-IF this was equal to the containing
start date.
ice-delivery-policy
element, but applies
to this specific ice-delivery-rule
element only.
If later than the stop date in the containing ice-delivery-policy
,
implementations MUST act AS-IF this was equal to the containing
stop date.
All of these attributes are conceptually joined with "AND" (not "OR"). That is, within a single delivery-rule, the valid delivery times are those times that satisfy all the restrictions listed in the attributes within the rule.
Putting it all together in a single example: consider a subscription in which updates could occur:
1.A nightly pull to update the day's business news.
2.A pull every thirty minutes during weekdays to get
updates.
3.A push on any day to correct errors or distribute
breaking news.
The delivery policy would look like:
<ice-delivery-policy startdate="1998-07-02T12:00:00"> <ice-delivery-rule mode="pull" starttime="02:00:00" duration="P7200S" maxcount="1" /> <ice-delivery-rule mode="pull" starttime="09:00:00" duration="P28800S" weekday="1 2 3 4 5" maxfreq="P1800s" /> <ice-delivery-rule mode="push" url="http://www.acme.com/ice-in/" /> </ice-delivery-policy>
In the ice-delivery-rule
, the ice-negotiable
elements describe which pieces of the ice-delivery-rule
are subject to negotiation (see section 4.5). The format is:
ice-negotiable |
<!ELEMENT ice-negotiable EMPTY > <!ATTLIST ice-negotiable min CDATA #IMPLIED max CDATA #IMPLIED type ( monthday | weekday | startdate | stopdate | starttime | duration | minfreq | maxfreq | mincount | maxcount ) #REQUIRED > |
This element provides input into the negotiation process by describing which parameters are explicitly negotiable, and by describing some limits on their values.
The attributes are:
ice-delivery-rule
is being described.
Note that in some sense the description in an ice-negotiable
element is a hint, not a mandate. If a Subscriber wishes to try
negotiating an attribute not listed in an ice-negotiable
,
the Subscriber MAY do so, and the Syndicator MAY
choose to accept the negotiated value. Similarly, a Subscriber
MAY choose to attempt to negotiate a value outside the
range, if one is specified. The intent of ice-negotiable
is simply to give guidance to the Subscriber negotiation implementation.
In spite of the hint nature of ice-negotiable
, a
Subscriber SHOULD attempt to abide by the restrictions
it describes, because a Syndicator is unlikely to accept a negotiated
value outside the described ranges.
A catalog contains subscription offers. A Subscriber typically begins an ICE relationship by obtaining the catalog of subscription offers from the Syndicator. This section defines the format of the catalog and the protocol operations for obtaining a catalog.
  | Informational Note |
  | for historical reference |
  |
The notion of the ice-catalog is
completely separate from the concept of "browsing a site
to find things you might want to subscribe to". HTML based
web pages are a more appropriate way for Syndicators to advertise
their offerings and to guide potential Subscribers through the
process of selecting an offering. Indeed, some of the manual
steps outlined regarding how a Syndicator and a Subscriber first
contact each other and exchange relevant authentication data
might be automated using HTML, JavaScript, applets, etc. The
ice-catalog is simply the way that the ICE tool
first obtains a set of offers that it can use to establish a
subscription; browsing an ice-catalog is not intended
to take the place of browsing a web site. |
ICE catalog format |
<!ELEMENT ice-catalog (ice-contact, (ice-offer-group | ice-offer)*) > |
<!ELEMENT ice-contact (#PCDATA) > <!ATTLIST ice-contact description CDATA #REQUIRED lang CDATA #IMPLIED name CDATA #REQUIRED sender-id CDATA #REQUIRED url CDATA #IMPLIED > |
<!ELEMENT ice-offer-group ((ice-offer-group | ice-offer)+) > <!ATTLIST ice-offer-group description CDATA #REQUIRED |
A catalog consists contact information, and zero or
more ice-offer
elements or groups of ice-offer
elements. Each ice-offer
contains a proposed set
of parameters for a subscription.
An ice-catalog
has no attributes.
Contact information is used for aiding human-to-human communication. The body of the element SHOULD contain human-readable text describing the primary points of contact. There are also several attributes:
ice-sender
.
An ice-offer-group
is simply a convenient way
to organize a set of offers together in a way that might make
sense to the Subscriber when viewing the catalog (i.e., the Subscriber's
ICE tool might provide a tree-view of this data). The only attribute
is:
The format of the ice-offer
structure is shown
here:
ICE offer format |
<!ELEMENT ice-offer (ice-delivery-policy, ice-business-term+) > <!ATTLIST ice-offer constraints-hash CDATA #IMPLIED constraints-hash-method CDATA #IMPLIED constraints-url CDATA #IMPLIED description CDATA #REQUIRED subscription-id CDATA #IMPLIED atomic-use (false | true) "false" editable (false | true) "false" ip-status CDATA #IMPLIED rights-holder CDATA #IMPLIED showcredit (false | true) "false" usage-required (false | true) "false" > |
An offer contains a delivery policy, already defined previously, a set of business terms (defined below), and the following attributes:
constraints-hash
.
Legal values for this attribute will be specified in the constraints
specification and are outside the scope of ICE itself.
ice-offer
appears
in an ice-status
response (i.e., within an ice-subscription
). Otherwise, MUST NOT
be present.
true
, indicates that all information
in the subscription must be used together, or not used at all.
If false
, or unspecified, then the Subscriber is
permitted to use subsets of the data in any way they want (and
as permitted by the legal licensing terms, of course). This flag
is meant to be useful as a hint/reminder displayed in a Subscriber's
ICE tool; obviously, ICE itself cannot enforce this semantic
(and, the use of lower case "must" in the above description
is intentional; there is no protocol requirement here).
true
, indicates that the Subscriber
may edit/alter the content before using it. If false
,
or unspecified, the Subscriber is expected to use the content
without any alteration. Same "hint" semantics as atomic-use
.
PUBLIC-DOMAIN
The content has no licensing restrictions, whatsoever.
FREE-WITH-ACK
SEE-LICENSE
SEVERE-RESTRICTIONS
CONFIDENTIAL
true
, indicates that the Subscriber
is explicitly expected to acknowledge the source of the data.
The ice-business-term
element is:
ice-business-term format |
<!ELEMENT ice-business-term (#PCDATA) > <!ATTLIST ice-business-term lang CDATA #REQUIRED type (credit | licensing | payment | reporting) #REQUIRED url CDATA #IMPLIED > |
Business terms are plain text, represented in the body of the element. The attributes are:
credit, licensing, payment,
and reporting
.
Credit refers to the type of acknowledgement ("giving credit")
required when using the content. Licensing refers to the general
terms of licensing. Payment refers to the cost and payment terms
expected when using the content. Reporting refers to the type
of end-user usage statistics expected when using the content.
Note that all of these terms are plain text descriptions. ICE
makes no attempt to programmatically explain licensing agreements;
rather, ICE is simply providing a transport mechanism allowing
user interfaces on the Subscriber side to easily locate, manage,
and display electronic copies of license agreements presumably
executed in the traditional way on paper.
Subscribers can use ice-get-catalog
to obtain
the list of subscription offers for which they are eligible. The
format is:
ICE get-catalog request format |
<!ELEMENT ice-get-catalog EMPTY > |
Return response is an ice-catalog
.
Typically, the Syndicator will look at the sender-id
field in the header to determine who the Subscriber is; if the
syndicator doesn't recognize the particular Subscriber the Syndicator
MAY return a 405 (Unrecognized sender) error code, or MAY
choose to allow the request anyway. Allowing the request anyway
is a policy decision made by the Syndicator as to whether anonymous
catalog browsing is permitted.
Note that Subscribers are not required to perform any ice-get-catalog
operations, ever. The only requirement is that eventually a Subscriber
knows how to fill in an ice-offer
request to establish
a subscription. It is possible, for example, for the parameters
for filling in that ice-offer
to come from some other
out-of-band mechanism such as an HTML/JavaScript application.
A Subscriber uses the ice-offer
request to establish
a subscription. Typically, a Subscriber will use ice-get-catalog
to get a catalog, take one of the ice-offer
structures
from that catalog, and send it back to the Syndicator in a request.
However, the Subscriber is free to create an ice-offer
structure in any implementation-defined manner it wants. For example,
a Syndicator might e-mail an ice-offer
to a Subscriber,
who could then feed it into their ICE tool and begin the protocol
processing here.
After the Subscriber sends the offer to the Syndicator, the Syndicator can respond in one of four ways:
ice-subscription
element.
This indicates that the Subscriber's offer was accepted and the
Subscriber is now subscribed as described in the response.
ice-offer
. This indicates the Syndicator is engaging
in parameter negotiation; see section 4.5 for details.
The simplest success case for establishing a subscription is
for the Subscriber to issue an ice-offer
request,
and the Syndicator to respond with a 200 (OK) code. If the Syndicator
responds with a negotiation response (code 440 or 441), the Subscriber
SHOULD enter into the parameter negotiation protocol as
outlined in section 4.5
ICE allows certain aspects of subscriptions to be negotiated so that the Syndicator and the Subscriber can reach mutually agreeable parameter values. It is important to understand that this negotiation model is for protocol-level parameter negotiation; it is not an attempt to automate the arcane and baroque nature of human-to-human business deal negotiation.
ICE supports negotiation for:
The flow of negotiation in ICE is based on the exchange of
ice-offer
elements. Each ice-offer
is
simply a set of parameters that the Sender would like to see the
Receiver accept.
The response to a proposal can be one of three things:
The Subscriber drives the entire negotiation process. Negotiation
begins with the Subscriber making an ice-offer
request
to the Syndicator. The Syndicator then does one of three things:
ice-subscription
response.
ice-offer
with the explicit 440 ("Sorry") error code.
ice-offer
with the explicit 441 ("Counter-proposal")
error code, and including a counter ice-offer
in
the response.
If the Subscriber receives a counter proposal, the Subscriber
MAY try another ice-offer
, either with the
contents of the counter proposal received from the Syndicator,
or with some other mixture of parameters. The method of choosing
what parameters to alter is a quality of implementation issue.
If the Subscriber receives a Sorry response, the Subscriber
MAY try again with some other ice-offer
, although
the Syndicator has (unhelpfully) not given any clues as to what
to try.
A Subscriber implementation MAY choose to never negotiate, simply always accepting the parameters proposed by the Syndicator. Such an implementation is called the Trivial negotiation implementation, and the protocol has been carefully designed to allow such implementations to exist and be conforming.
To Subscribe to a subscription, a Trivial Negotiation implementation
simply obtains an offer using ice-get-catalog
. It
then picks an offer from the catalog. There might be multiple
offers to choose from, especially if the Syndicator is equipped
with negotiation logic. A Trivial implementation SHOULD
just pick the first offer and send it to the Syndicator in an
ice-offer
request.
Ignoring error conditions, which would be handled the usual way, there are three possible outcomes:
ice-response
. At this point, the subscription
"negotiation" is concluded.
ice-offer
response). Again, the Syndicator might do this because of changing
circumstances since the original proposal was made. The Trivial
Negotiation implementation SHOULD handle this by issuing
a new ice-offer
request to accept the counter proposal.
Thus, the minimal message flow in a trivial negotiation is:
If there is one round of negotiation, it looks like this:
Another scenario would be the Syndicator rejecting an offer with a simple "Sorry". Note that this can happen even if the offer came from the catalog (as already discussed). This would look like this:
As mentioned, even a trivial implementation SHOULD implement some form of policy that limits the number of times the negotiation loop will be executed.
Any implementation that does more than what is described for the Trivial implementation is, by definition, a Non-trivial negotiation implementation.
Typically, what distinguishes a Non-trivial negotiation implementation from a Trivial one is its ability to create counter proposals on its own. The most useful application of this technique is in the area of delivery schedules. Consider a push-based subscription. The Syndicator software can implement load balancing by attempting to spread delivery times around the hour. A Subscriber with many subscriptions might wish to do the same thing. Thus, the first delivery schedule proposed by a Syndicator might not be one that the Subscriber wishes to accept. A Non-trivial negotiation implementation on the Subscriber would ignore the Syndicators schedule proposal and offer its own preferred proposal.
There are some implementation guidelines designed to increase the probability of a successful negotiation outcome:
ICE defines a number of status operations for manipulating subscriptions. They are:
Each is described below.
Cancels a subscription. This can be issued by either the Syndicator or the Subscriber. The format is:
ICE cancel format |
<!ELEMENT ice-cancel EMPTY > <!ATTLIST ice-cancel subscription-id CDATA #REQUIRED reason CDATA #REQUIRED lang CDATA #REQUIRED > |
The attributes are:
reason
.
When a Subscriber sends an ice-cancel
to a Syndicator,
the two most likely types of response are:
ice-cancellation
(described below).
subscription-id
in the request.
The subscription doesn't exist and there is no need to ever try
this particular cancel operation again.
The Subscriber should interpret any other error code as best
it can. One possible way for the Subscriber to tell if the Syndicator
thinks it is still subscribed is to use ice-status
to obtain the list of active subscription-id
values.
The ice-cancellation
returned in a successful
response is:
ICE cancel results |
<!ELEMENT ice-cancellation EMPTY > <!ATTLIST ice-cancellation cancellation-id CDATA #REQUIRED subscription-id CDATA #REQUIRED > |
The attributes are:
subscription-id
in the ice-cancel
request.
Changes a subscription. This can be issued by either the Syndicator or the Subscriber. The semantics of this request are that a new parameter negotiation process is begun; however, until the negotiation process is completed successfully, the existing parameters remain in force.
The format of ice-change-subscription
is:
ICE change subscription format |
<!ELEMENT ice-change-subscription EMPTY > <!ATTLIST ice-change-subscription subscription-id CDATA #REQUIRED > |
There is only one attribute:
There are two cases to consider: Subscriber-initiated changes and Syndicator initiated changes.
When the Subscriber wishes to initiate a subscription change, the sequence of requests is as follows:
ice-change-subscription
to the Syndicator.
ice-offer
in the response. The ice-offer
in the response indicates
the ranges of parameters the Syndicator is willing to renegotiate
at this point.
subscription-id
in all ice-offer
elements sent to the Syndicator,
so that the Syndicator can distinguish between original negotiation
and renegotiation.
The existing subscription parameters always remain in force
until an ice-offer
is accepted with 200 (OK) by the
Syndicator.
When the Syndicator wishes to initiate a subscription change:
ice-change-subscription
to the Subscriber.
ice-offer
in the response (if an ice-offer
is supplied it
is ignored by the Syndicator).
While renegotiation is active, the Syndicator MAY reject other requests on this subscription with the 442 (Renegotiation in progress) error code.
The Syndicator MAY, by rejecting requests with 442 (Renegotiation
in progress), initiate renegotiation without ever sending an ice-change-subscription
.
If a Subscriber receives a 442 error code and is not already engaged
in renegotiation on that subscription, the Subscriber MUST
enter into the ice-change-subscription
renegotiation
process.
Obtains status information for a subscription. This can be issued by the Subscriber to the Syndicator. The format is:
ICE get status format |
<!ELEMENT ice-get-status EMPTY > <!ATTLIST ice-get-status subscription-id CDATA #IMPLIED> |
<!ELEMENT ice-status (ice-contact, ice-subscription+) > |
<!ELEMENT ice-subscription (#PCDATA) > <!ATTLIST ice-subscription subscription-id CDATA #REQUIRED current-state CDATA #IMPLIED expiration-date CDATA #IMPLIED quantity-remaining CDATA #IMPLIED expiration-priority (first | last) #IMPLIED > |
There is only one attribute for ice-get-status
:
The response is an ice-status
, containing ice-contact
contact information and ice-subscription
data. There
are no attributes on ice-status
.
The ice-subscription
element describes the state
of a particular subscription. There are several attributes:
Package delivery in ICE follows a Sequenced Package Model. This section describes that model. In this first description, the basic concepts are introduced without regard for the specific protocol messages used to realize the semantics of the model. Later sections will describe the specific messages.
An ICE subscription consists of a discrete set of packages
delivered, in order, over a period of time. Consider the following
diagram representing the delivery of individual packages, each
labeled P
and positioned along a timeline:
----|-----P-----P-------P-----P------P--------P----P-----> t t=0
ICE defines the term collection to mean the set of items received over time. In the Headlines.com example discussed in 2.1.1, the collection consists of all the headline text, thumbnail images, etc., existing on a Syndicator or Subscriber's site at any point in time. In the Parts Information Scenario described in 2.1.2, the collection consists of the complete set of service bulletins, price lists, etc., again as it exists at any one point in time.
ICE uses the package as the atomic unit of collection manipulation; the only way for a Syndicator to change a Subscriber's collection is for the Syndicator to send a package to the Subscriber (push or pull). It is not possible for the Syndicator to send a "naked" file unless it is part of a package. Similarly, a Subscriber cannot request an update for an individual file; the only thing the Subscriber can do is request a new package of updates from the Syndicator.
It follows from this model that the state of a Subscriber's collection is completely described by knowing the set of packages the Subscriber has received over time
ICE forces a Syndicator (and a Subscriber) to view the package stream as a strictly ordered sequence of packages. This means that packages cannot be processed out of order, and all intermediate packages must be processed.
For explanatory purposes, assume for the moment that packages were numbered P1 for the first package, P2 for the second, etc., In this case the strictly ordered package model of ICE requires that the Subscriber always process package PN-1 before processing package PN.
This model may seem at first glance to be a poor match for certain types of syndications, where intermediate updates might not be important. For example, in the Headlines.com example, if a Subscriber misses 10 days of headlines, it might be perfectly reasonable for the Subscriber to simply get the current set of headlines and ignore the intervening packages. The ICE model does, in fact, allow for this type of Syndication; this will be explained in a moment.
Given that ICE defines a package as the atomic unit of collection manipulation, and given that ICE forces a Subscriber to process all packages in a strict order, it is possible for a Syndicator (or Subscriber) to completely describe the state of the Subscriber's collection with a single value: namely, an identifier indicating the position of the Subscriber within the ordered sequence of packages.
Thus, if packages were numbered with integers, consider the
following package sequence:
----|-----P1----P2------P3----P4-----P5------P6----P7-----> t t=0
In this example, simply knowing the number of the last package successfully processed by a Subscriber will suffice to know the complete state of the Subscriber's collection. For example, knowing that the Subscriber is "in state 5", meaning, has received and correctly processed package number 5, implies that the Subscriber's collection is in the state that would be achieved by starting in an empty state, and processing packages 1 through 5, in order. Thus, a simple number by itself, e.g., "5", suffices for describing the state of the Subscriber's collection. In ICE, this "number" is called a Package Sequence Identifier, and is actually not a number at all, but rather an opaque string per the following definition:
Definition: A Package Sequence Identifier is an opaque string, generated by a Syndicator, representing the state at the boundary (before or after) of package processing. Each package sent by a Syndicator to a Subscriber has two package sequence identifiers attached to it: an "old" state value representing the required state before processing the package, and a "new" state value representing the resulting state after processing the package.
Note that the identifier is completely opaque to the Subscriber. This gives the ICE implementation on the Syndicator the complete flexibility to use an implementation-specific method for encoding state into this identifier. For example, the implementation might use integers as described above, or it might use timestamps, or it might use a unique key into a proprietary database as the state encoding mechanism. All of these methods are permitted, and the opaqueness of the identifier guarantees that (properly-implemented) Subscribers will not be affected by these choices.
ICE defines three distinguished values for Package Sequence Identifier strings:
Furthermore, ICE reserves all Package Sequence Identifier strings
beginning with ICE-
(capital I, capital C, capital
E, hyphen). All other values of a Package Sequence Identifier
are controlled by the Syndicator and are completely opaque to
the Subscriber.
The requirements for Subscribers regarding Package Sequence Identifiers are:
ICE-INITIAL
, ICE-ANY
)
as described above.
When a Syndicator delivers a package to a Subscriber, whether by push or pull, the package contains two sequence identifiers: the old-state, which represents the state the Subscriber must be in before applying the package, and the new-state, which represents the state the Subscriber will be in after applying the package.
Assume, for example, that a Syndicator is using the names of people as the Package Sequence Identifier. Using this method, a set of packages delivered over time might consist of:
First Package: old-state: ICE-INITIAL new-state: STEVE Next Package: old-state: STEVE new-state: GREG Next Package: old-state: GREG new-state: ROGER
As will be shown in more detail later, a Subscriber is required
to store its current Package Sequence state at all times. When
it first starts a new subscription, the Subscriber starts in state
ICE-INITIAL
. In the above example, the first package
the Subscriber receives must have an old-state of ICE-INITIAL
(or ICE-ANY
, which will be discussed next). If, due
to some operational error, the Subscriber were to receive the
wrong package, e.g., one that said old-state: GREG
instead of old-state: ICE-INITIAL
, then the Subscriber
would know not to process that package and to raise an error condition.
The above model works well for subscriptions requiring a strict, fully-reliable, replication of state from a Syndicator to a Subscriber. The Package Sequence model strictly forces the Subscriber to receive all packages in their proper order, and process them each individually. The protocol does this by requiring the Subscriber to remember its current Package Sequence Identifier, and to send that Identifier to the Syndicator when requesting a package update (for pull; push subscriptions are slightly more complex and will be discussed later). Thus, the Syndicator always knows what state the Subscriber is in, and the Syndicator can thus always compute what the "right" next package to send to the Subscriber.
Some models of subscriptions do not require the rigor of this
model. As mentioned, the Headlines.com model can be implemented
in a much simpler fashion: each package is actually a full update
of the Subscriber, and there are no dependencies on intervening
packages. The ICE Package Sequence model accommodates this type
of subscription using the ICE-ANY
value. When ICE-ANY
appears in the "old-state" of a package, it means that
the package can be applied by a Subscriber regardless of what
state the Subscriber is in.
By using combinations of ICE-ANY
preconditions
and specific preconditions, a Syndicator can also implement hybrid
models where some packages are useful regardless of the Subscriber's
current state.
An example will help tie this all together. To understand the
example, assume for the moment that packages can contain files,
and that they can also contain "remove" operations that
refer to files delivered in previous packages. As will be explained
later, packages can indeed contain these types of things, albeit
in a much more general (and complex) way (because packages are
not limited to operating only on files).
A Syndicator provides a restaurant review service; Subscribers
receive updates with new restaurants, new information about existing
restaurants, etc.
/restaurants/<<<restaurant-name>>>.html
/restaurants/index.html
file is sent each
time to provide navigation
Assume for the moment that the service is just starting up and there is only one Subscriber. The service is launched with only 3 restaurant reviews. The package stream generated over time by the Syndicator might look something like this:
package P1: add /restaurants/bobs.html add /restaurants/joes.html add /restaurants/moms.html add /restaurants/index.html
package P2: comment: a new restaurant opened, and bob's is updated add /restaurants/anns.html update /restaurants/bobs.html update /restaurants/index.html
package P3: comment: someone burned mom's place down remove /restaurants/moms.html update /restaurants/index.html
At this point assume that a new Subscriber signs up. That Subscriber
needs all three packages P1, P2, P3, in that order. The Syndicator
will know this because the Syndicator (by definition) knows that
it is currently in state "P3", and it will know that
the Subscriber is in state ICE-INITIAL
when the Subscriber
requests its first update.
Note that, as an implementation optimization, the Syndicator can construct a special "catch up" package in this case. That would look like this:
add /restaurants/anns.html add /restaurants/joes.html add /restaurants/bobs.html add /restaurants/index.html
A Syndicator implementation that does that might be more efficient than sending all three incremental updates. But whether or not this should be done is a quality-of-implementation decision made by the Syndicator. Nothing in the sequenced package model dictates one approach or the other.
Finally, assume one more package needs to get sent, this time to two Subscribers:
package P4: comment: mom's is back, and there's another update for bob's add /restaurants/moms.html update /restaurants/bobs.html update /restaurants/index.html
As mentioned before, the Subscriber must keep track of the
sequence identifier of the last successfully processed package.
The Subscriber sends this sequence identifier back to the Syndicator
when requesting an update, so that the Syndicator can understand
the Subscriber's state. The Syndicator contains the logic to understand
what to do based on the Subscribers (stated) sequence identifier.
In the case of an unreliable update model, the Syndicator can
basically ignore the sequence identifier and just send the current
package (with an old-state of ICE-ANY
). In other
models, the Syndicator can compute what to send by decoding the
sequence identifier (which it generated in an earlier package)
and using that to determine what to send.
This shows the messages exchanged in the above example when
the new Subscriber was added between Time 3 and Time 4 in the
above sequence.
SUB-->SYN I'm subscribing to RESTAURANTS SYN-->SUB OK SUB-->SYN GetPackage, my state is ICE-INITIAL SYN-->SUB - three packages P1, old-state: ICE-INITIAL new-state: XYZ-1 P2, old-state: XYZ-1 new-state: XYZ-2 P3, old-state: XYZ-2 new-state: XYZ-3
Alternatively, this last message could have been:
SUB-->SYN I'm subscribing to RESTAURANTS SYN-->SUB OK SUB-->SYN GetPackage, my state is ICE-INITIAL SYN-->SUB - one package Px, old-state: ICE-INITIAL new-state: XYZ-3
where the "Px" package would be a customized package
designed specifically to get a Subscriber from the initial state
to the current state. The key point is the separate specification
of a list of packages to be received, and an explicit statement
about what the state will be after processing the packages.
It is entirely the Syndicator's discretion as to what the best
way to update the Subscriber is (e.g., sending all the incremental
packages or sending a special catch up package).
Suppose the Subscriber comes back before Time 4 and asks for an
update:
SUB-->SYN GetPackage, my state is XYZ-3 SYN-->SUB 202 Package sequence state already current
Later, there are updates available:
SUB-->SYN GetPackage, my state is XYZ-3 SYN-->SUB one package: P4, oldstate XYZ-3, new XYZ-4
ICE packages contain content as a set of idempotent operations: remove and add. These operations use the addressing mechanism of a subscription element to reference and manage delivered content. The method of delivery does not affect these operations. As detailed in the Sequenced Package Model section, each package moves the subscription from an old state into a new state of the subscription.
ICE package format |
---|
<!ENTITY % cm.content "ice-item-group | ice-item | ice-item-ref" > <!ENTITY % cm.package "((ice-item-remove+, (%cm.content;)*) | (%cm.content;)+)" > <!ELEMENT ice-package (%cm.package;) > <!ATTLIST ice-package activation CDATA #IMPLIED atomic-use (false | true) "false" confirmation (false | true) "false" editable (false | true) "false" exclusion CDATA #IMPLIED expiration CDATA #IMPLIED fullupdate (false | true) "false" lang CDATA #IMPLIED new-state CDATA #REQUIRED old-state CDATA #REQUIRED package-id CDATA #REQUIRED show-credit (false | true) "false" subscription-id CDATA #REQUIRED > |
The attributes are:
ice-code
messages such as 201 (Confirmed).
It is assigned by the Syndicator.
An ice-package
describes a set of content operations:
removals and additions. The remove operation is specified using
the ice-item-remove
element. The content additions
contain the content that needs to be added or updated and are
specified using the ice-item
and ice-item-ref
elements. The ice-item-group
element allows the Syndicator
to associate the content specified using the ice-item
elements together. For example, in the restaurant reviews example,
each review may consists of different types of content: an HTML
file and two graphic files for example. These three files could
be contained within three ice-item
elements and grouped
together in an ice-item-group
as a single restaurant
review. Likewise, unrelated content can be specified in an ice-package
by just using the ice-item
elements without an intervening
ice-item-group
. The ice-item
and ice-item-ref
elements distinguish themselves by the way they contain the content.
The ice-item
element is used to contain content directly
in the delivered content. The ice-item-ref
element
is used to distribute an indirect reference to the actual content.
The content model of the ice-package
element is
constructed so that it MUST contain some operation; at
a minimum, a single removal or a single addition. If there are
removal operations, they MUST be specified and, therefore,
performed before any additions. It is possible that an ice-package
only contains removal operations. Alternatively, an ice-package
may consist entirely of additions. The ice-package
specifies an old-state and a new-state. Before the new-state can
be reached, all of the operations contained within a package MUST
be processed, and, if constraints are specified, the constraints
MUST be met as well. If an operation can not be performed
successfully, all previously performed operations specified in
the package MUST be undone, so the Subscriber is not left
in an inconsistent state with regards to the package sequence,
and a surprise ice-code
message MUST be delivered
to the Syndicator indicating the type of error that occurred,
such as 420 (Constraint failure). All of the operations are idempotent,
i.e., it is not an error if the same content is added more than
once, nor is it an error if a remove operation does not find the
element to remove. In both cases the results are the same (an
add operation resulted in the content existing on
the Subscriber's system, and a remove operation resulted in the
content not existing).
The details of the additions and removals are described within
their respective sections. XML parameter entities were used to
construct the ice-package
content model to modularize
the description and to allow for reuse of the content model (notice
that the cm.content
entity is used for the ice-item-group
content model below).
ICE provides three operations by which packages can add new
content to the Subscriber's collection: ice-item
,
ice-item-ref
, and ice-item-group
.
Each is described below.
ice-item |
---|
<!ENTITY % cm.item "#PCDATA" > <!ELEMENT ice-item (%cm.item;) > <!ATTLIST ice-item activation CDATA #IMPLIED content-filename CDATA #IMPLIED content-transfer-encoding (base64 | x-native-xml) "x-native-xml" content-type CDATA "application/octet-stream" item-id CDATA #REQUIRED lang CDATA #REQUIRED name CDATA #REQUIRED subscription-element CDATA #IMPLIED > |
The attributes are:
activation
attribute
has been set in a containing element, those semantics MUST
apply, otherwise, if no containing element has an activation
attribute, the content contained within the ice-item
is available for the Subscriber to deploy at their discretion.
ice-item
element. The only valid values are x-native-xml
and base64
. These values are derived from RFC-2045,
sections 6.2 and 6.3. The x-native-xml
encoding
indicates that character entities may have been used to protect
the special characters identified in section 2.4 of the XML 1.0
W3C Recommendation. It is an experimental encoding. The base64
encoding exhibits the same properties as that defined in section
6.8 of RFC 2045. The base64
encoding provides a
means to distribute binary data such as graphics formats and
other humanly unreadable data formats. Future versions of ICE
may expand on this set of values.
application/octet-stream
, indicates the opaque
nature of the content being distributed.
ice-item
elements with names such as "headline", "author", "pub-date", etc.
subscription-element
identifier in an operation in a subsequent package. Alternatively,
a full update will be required that will remove all of the content
associated with the subscription.
The ice-item
element explicitly contains the content
being distributed. The default content model for an ice-item
is simply character data. The data MUST conform to the
definition of character data in XML. Binary data can be transmitted
within an ice-item
by using a base64 encoding. The
content model for an ice-item
MAY be overridden
by other XML ELEMENT
declarations, this does not
affect the operational semantics of the element itself. To replace
ice-item
, please refer to the Extensibility section
below. The purpose of the name
attribute is to represent
in a generic way what specific markup might represent if both
parties had agreed to a common vocabulary and had specific applications
for handling the content. For example, what gets represented as
<ice-item name="headline">
might
be more specifically marked up using <headline>
using XML as the markup language. This element allows for quick
deployment of the content without a lot of up-front investment
and because the content models are extensible, the investment
in specific markup vocabularies can be similarly expressed within
the same protocol.
ice-item-ref |
---|
<!ELEMENT ice-item-ref EMPTY > <!ATTLIST ice-item-ref activation CDATA #IMPLIED item-id CDATA #REQUIRED name CDATA #REQUIRED subscription-element CDATA #IMPLIED url CDATA #REQUIRED > |
The attributes in common with ice-item
have the
same semantics:
All other attribute semantics are identical to ice-item
.
The processing of this operation requires resolving the reference
and obtaining the content associated with it. Failure to resolve
the reference or obtain the content MUST cause a surprise
ice-code
message, 431 (Failure fetching external
data), to be sent to the Syndicator.
ice-item-group |
---|
<!ELEMENT ice-item-group ((%cm.content;)+) > <!ATTLIST ice-item-group activation CDATA #IMPLIED item-group-id CDATA #REQUIRED name CDATA #IMPLIED subscription-element CDATA #IMPLIED > |
The attributes for ice-item-group
have the same
semantics as the ice-item
element with the following
exceptions.
The ice-item-group
element allows relationships
among content items to be expressed. For example, a story or headline
could be individually described as content items within one of
these groups. The content model for an ice-item-group
allows for the nesting of groups and individual content items.
The identifier on the group is assigned by the Syndicator and
is scoped within the package. The name is for logging purposes
and otherwise has no semantics associated with it. The availability
of the subscription-element
attribute allows for
coarser operations to occur. For example, a subsequent package
might contain a remove operation identifying the group's subscription-element
identifier that MUST be used to remove all individual items
previously contained within that group. Likewise, any updates
or adds associated with the same group's subscription-element
associates the individual items together.
Similar to archiving packages, groups with subscription-element
identifiers allow for other items to be added over a sequence
of packages. Consider a package that delivered a group identified
as subel3 with three content items. In a subsequent package
that delivers a group identified as subel3 with four different
items, the resulting addition of the four will yield a group containing
seven items. If any of those items also contained subscription-element
attributes, they would be replaced, so the yield would be less.
This is similar to the case where a tar file specifying a directory
with three files being extracted, and later on receiving a tar
file with the same directory specified but four different files.
The contents of the directory would be seven files (unless there
were files with the same name in the archive). There is a difference
between an archive file delivering directories and files with
the ICE package containing groups and items that groups have no
physical manifestation, but groups with a subscription-element
attribute requires the Subscriber to manage the content contained
within that group.
ice-item-remove |
---|
<!ELEMENT ice-item-remove EMPTY > <!ATTLIST ice-item-remove subscription-element CDATA #REQUIRED > |
The attribute is:
The subscription-element
attribute on the ice-item-remove
element identifies the content item (or group of content items)
that MUST be removed from a Subscriber's system. The physical
location(s) of the content that needs to be removed MUST
be managed by the Subscriber. A full update of content items can
be achieved by a Syndicator in one of a number of ways. Two specific
ways are either to enumerate all of the subscription element identifiers
in a set of ice-item-remove
elements followed by
the new content in a set of ice-item
elements or
to specify the fullupdate
attribute on the ice-package
element to have a value of true
. This remove request
can be seen as a logical removal in the sense that the end result
after processing the whole package must be that the content specified
in the ice-item-remove
element must be removed from
the Subscriber's system. During an intermediate stage of processing,
it may mean that the remove has not occurred until the very end
because the content is being updated in an add operation. In this
case the add operation overrides the remove.
The content models of the ice-package
and
ice-item
, elements MAY be extended
or replaced with declarations of different elements or content.
See Appendix A.
If a subscription has a delivery policy method of type pull,
the Subscriber must initiate the delivery of the packages with
the ice-get-package
request. When a Subscriber requests
a package from the Syndicator, the Subscriber MUST provide
the state of the subscription and subscription identifier, and
MAY provide an application-specific parameter value.
The message format is:
ice-get-package |
---|
<!ELEMENT ice-get-package EMPTY > <!ATTLIST ice-get-package current-state CDATA #REQUIRED parameter CDATA #IMPLIED subscription-id CDATA #REQUIRED > |
The attributes are:
When a Subscriber sends an ice-get-package
to
a Syndicator, the most likely types of response are:
ice-package
elements.
ice-get-status
request to learn what state the Syndicator thinks the Subscriber
should have, or perform some other communication (perhaps including
ice-notify
) with the Syndicator.
The Subscriber should interpret any other return code as best
it can. The number of ice-package
elements and the
number of state transitions that are provided in a single response
is determined by the quality of implementation of the Syndicator's
ICE application.
If a subscription has a delivery policy method of type push,
the Syndicator must initiate the delivery of the packages with
the ice-request
containing one or more ice-package
elements. When a Syndicator sends a package to the Subscriber,
the Syndicator MUST provide the expected state of the subscription
before and after the package is processed. The Subscriber is still
responsible for maintaining the current state of the subscription,
but the Syndicator now has that responsibility to support push
operations. The message format is defined in section 5.2.1 Package
format.
When a Syndicator sends an ice-package
request
to a Subscriber, the most likely types of response are:
ice-package
.
The Syndicator should interpret any other return code as best it can.
This section contains all other package-related protocol operations.
When a Syndicator requests confirmation from a Subscriber, the Syndicator MAY choose to allow a certain number of additional operations to occur while that confirmation request is still outstanding. The number, and type, of such requests that the Syndicator will honor in the interim is a quality of implementation issue and a Syndicator policy issue.
Eventually, the Syndicator might want to indicate its unwillingness to proceed any further until the Subscriber furnishes the expected pending confirmations. ICE provides two different methods for the Syndicator to indicate this. First, the Syndicator MAY return error code 602 (Excessive confirmations outstanding) on any request made by the Subscriber. This is a "passive" way for the Syndicator to indicate its displeasure; passive in the sense that the Subscriber will not find out about it until the Subscriber makes a request.
The second method ICE provides is the ice-send-confirmations
message. This message allows the Syndicator to tell the Subscriber
explicitly that it is expecting confirmations and is puzzled as
to why it hasn't received them yet.
The message format is:
ice-send-confirmations format |
<!ELEMENT ice-send-confirmations EMPTY > <!ATTLIST ice-send-confirmations subscription-id CDATA #IMPLIED > |
The attributes are:
The proper response to this message is for the Subscriber to
return a code telling the Syndicator whether the Subscriber agrees
or not that there are outstanding confirmations. If the Subscriber
agrees that there are outstanding confirmations on this subscription,
the Subscriber MUST return ice-code
200 (OK).
If the Subscriber does not have any outstanding confirmations
on this subscription, the Subscriber MUST return ice-code
303 (No more confirmations to send). Notwithstanding those two
requirements, the Subscriber MAY return any arbitrary error
code to indicate other processing problems. So, for example, an
ice-send-confirmations
request that does not validate
might still generate a 402 code.
ICE provides a mechanism allowing the Subscriber to get
information about package ordering and potential optimizations.
The Subscriber does this with an ice-get-sequence-info
request. In this request, the Subscriber
sends its current package sequence state, and a set of package
identifiers and their ("new-state") package sequence state values.
The request returns
a sorted, and potentially optimized (as described below), list of
the packages and sequence identifiers.
The message format is:
ice-get-sequence-info format |
<!ELEMENT ice-get-sequence-info (ice-package-id-seq)+ > <!ATTLIST ice-get-sequence-info subscription-id CDATA #REQUIRED > |
<!ELEMENT ice-package-id-seq EMPTY > <!ATTLIST ice-package-id-seq package-id CDATA #REQUIRED sequence-id CDATA #REQUIRED > |
There is only one attribute on the ice-get-sequence-info
element:
The ice-get-sequence-info
element contains one or more
ice-package-id-seq
elements, each of which contains
a package identifier and the sequence identifier that was found
in the new-state
of that package.
The response is an ice-sequence-info
, as shown here:
ice-sequence-info format |
<!ELEMENT ice-sequence-info (ice-package-id-seq)* > <!ATTLIST ice-get-sequence-info subscription-id CDATA #REQUIRED > |
The response contains a sorted list of ice-package-id-seq
elements. This list might be a subset of the elements sent in the
ice-get-sequence-info
request, if the Syndicator determines
that some of the intervening packages need not be processed by the Subscriber.
The ice-repair-item
request
allows a Subscriber to ask for
a replacement copy of an individual asset in a collection. The intent
is to provide a mechanism for repairing a Subscriber's collection
after minor mishaps, such as a file being accidentally deleted.
The message format is:
ice-repair-item format |
<!ELEMENT ice-repair-item EMPTY > <!ATTLIST ice-repair-item subscription-id CDATA #REQUIRED subscription-element CDATA #REQUIRED current-state CDATA #REQUIRED > |
The attributes are:
In making this request, the Subscriber is asking the Syndicator to return a copy of the asset as of the given package sequence state, if it is able to do so.
When a Syndicator receives this request, there are at least four possible responses it can make:
ice-package
,
with a "true" item-repair
attribute. The package in
this case will contain the requested asset.
Note that this request is provided for the convenience of the Subscriber, in the hopes that in some cases the Syndicator might be able to easily supply a replacement asset. The request does not obviate the requirement for a Subscriber to perform backup processes; in particular since the Syndicator is always allowed to return an error (including 503) on this request, the Subscriber MUST NOT assume that individual asset repair requests will work.
ICE allows a Syndicator to request the protocol event logs of the Subscriber, and vice-versa, as an aid for debugging and diagnosis. This section describes the protocol operations for manipulating log files.
ICE does not impose a particular format on the data contained in the logs. There are a number of reasons for this, the most compelling reason being that there are a variety of other efforts underway to define log file formats (e.g., XLF). For interoperability at the ICE level, the only requirement is that one system know how to ask another system for a log file and that ICE be able to transport multiple log file formats. Beyond that, the two systems can agree at the application layer as to what those log files will actually contain.
ICE does in fact define one log file format, called the "ice" format. Section 6.3 describes this format.
Event logs consist of implementation-defined data collected and recorded by the ICE tools used on each side of the relationship. There is only one meaningful operation that can be applied to event logs: they can be requested. This request can be made by the Subscriber, to obtain the Syndicator logs, or by the Syndicator, to obtain the Subscriber logs.
The format of this ICE request is shown below:
<!ELEMENT ice-get-events EMPTY > <!ATTLIST ice-get-events format NMTOKENS #IMPLIED start CDATA #IMPLIED stop CDATA #IMPLIED subscription-id CDATA #IMPLIED > |
The attributes are:
ice-get-events
request. (This is not a "must not" because it has no
effect on protocol interoperability).
The response is an ice-events
message, as shown here:
<!ENTITY % cm.events "ice-event-log" > <!ELEMENT ice-events (%cm.events;) > <!ATTLIST ice-events format CDATA #REQUIRED start CDATA #IMPLIED stop CDATA #IMPLIED subscription-id CDATA #IMPLIED > |
The attributes are:
In the case where format is "ice", the content model of the
ice-events
element is an ice-event-log
,
as described next (6.3).
Note that the content model of the ice-events
element MAY be extended
or replaced with declarations of different elements or content.
See Appendix A.
This section describes the "ice" format, which is just one log file
format that can be transported by ice-get-events
.
ICE implementations SHOULD support this format, and MAY
support other formats as well.
The "ice" format log consists of an ice-event-log
wrapper, containing a number of ice-event-msg
and
ice-event-info
elements, as shown here:
<!ELEMENT ice-event-log ((ice-event-msg | ice-event-info)*) > <!ATTLIST ice-event-log version CDATA #REQUIRED > |
<!ELEMENT ice-event-msg (ice-code?, ice-event-data?) > <!ATTLIST ice-event-msg other-id CDATA #IMPLIED request CDATA #REQUIRED request-id CDATA #REQUIRED request-start CDATA #REQUIRED request-type CDATA #IMPLIED response CDATA #REQUIRED response-id CDATA #IMPLIED response-stop CDATA #REQUIRED response-type CDATA #IMPLIED role (requestor | responder) #REQUIRED subscription-id CDATA #IMPLIED > |
<!ELEMENT ice-event-info (ice-event-data?) > <!ATTLIST ice-event-info event CDATA #REQUIRED event-start CDATA #REQUIRED event-stop CDATA #REQUIRED > |
In an ice-event-log
, there is only one attribute:
The ice-event-log
contains zero or more ice-event-msg
or ice-event-info
elements.
The ice-event-msg
element represents a record of an
ICE protocol event. It contains logging information about both the
request and the corresponding response.
The attributes are:
sender-id
)
of the other party in the communication.
request-type
).
ice-event-msg
must indicate whether the event was
initiated by the logger (role="requestor"
) or by the other
party (event role="responder"
).
Within the ice-event-msg
itself is an ice-code
,
logging the code that came back in the response (if any), and
an ice-event-data
element, which has an ANY
content model and allows loggers to record additional data in
an implementation-specific format.
This information is completely
implementation dependent, determined by the Sender of the log, and can
safely be ignored by the Receiver. It is expected that as interoperable
ICE implementations arise, it will become clear what additional
information is valuable to log, and that additional information may be
added to a future version of this specification. Note that ICE reserves
all element names beginning with the sequence "ice-", so additional,
implementation-defined sub-elements MUST obey this restriction in order
to avoid conflict with future versions of the ICE event log format.
The ice-event-info
element provides a way to log
other information events not directly related to protocol operations.
The attributes are:
The strings in the event
attribute have the following
meanings:
ice-up
and simple-ice-up
events.
ANY
content model of the ice-event-data
element.
ANY
content model of the ice-event-data
element.
All standardized information in the ice-event-log
is transmitted as attributes. This is done so that the logs are easy to
scan using standard pattern matching tools, as well as making efficient
use of XML parsers, while the ice-code
and implementation-defined
additional information is transmitted in the body of the element where
it can be retrieved as needed.
Note that while ICE can specify the format of communication of
ICE events, it leaves the details of how logging is controlled, and
indeed whether any logging is done at all, as a quality of implementation
issue. It is perfectly legal for an ICE implementation to never log
anything, and always return an empty log in response to an ice-get-events
request.
That being said, it is expected that logging will be useful for debugging
and diagnosis, and the ability to share logs between Subscriber and
Syndicator will help in managing the relationship.
This section describes protocol operations that don't fit into any other category.
The ICE no-op (ice-nop
) operation is useful for
debugging and diagnosis. Subscribers MAY also use it as
a way to poll for the unsolicited-pending
flag.
The format of ice-nop
is:
ice no-op |
<!ELEMENT ice-nop EMPTY> |
There are no attributes, and these is no element body. The response message is normally just a 200 (OK) code.
The no-op request can be sent by Subscribers or Syndicators.
ICE provides a way for an administrator on either the Subscriber or the Syndicator to send a text message to the other system. The intent is that these text messages would be taken by the ICE tool and displayed to an appropriate user in some form. These messages are a good way to communicate planned system level events such as planned down time, or expected changes in the nature of the subscription ("starting next week, we're shipping 100MB of video files with every headline"), etc.
ICE provides no semantic interpretation of the message content whatsoever.
The format of the ice-notify
request is:
ice notify |
<!ELEMENT ice-notify (#PCDATA)> <!ATTLIST ice-notify priority (1 | 2 | 3 | 4 | 5) #REQUIRED > |
The body of the element contains the text message. The sole attribute is:
ICE was designed to allow for other XML markup to be used within
its framework using XML facilities, but without modifying the
ICE DTD itself. This gives ICE applications and users the ability
to use ICE beyond what the authors had originally designed. There
are three specific areas of extensibility that the authors felt
were important to allow for alternative markup: the format of
the events returned in the ice-events
response, the
content contained within the ice-item
element, and
the markup used within an ice-package
element. In
all three cases, the basic mechanism is the same, but the implications
and expectations of extending the markup changes slightly.
Three package formats exist for delivering content using ICE.
ice-item
and ice-item-group
elements as outlined in 5.2 (Package containment model). ICE
implementations MUST support content distributed using
this definition. ICE implementations MUST support the
inclusion of opaque application data as the content of an ice-item
.
ice-item
element with domain-specific element declarations as described
in A.2. ICE implementations SHOULD allow the inclusion
of XML-formatted data in an ice-item
because it
allows XML validation of the included data. The behavior of ICE
implementations MUST be the same as if the content were
totally opaque as defined in the previous format.
ice-package
element with domain-specific element declarations, adding ICE-specific
attributes to any of the domain-specific element declarations.
ICE implementations MAY support Syndicators who modify
or extend ice-package
as described in A.3.
If the event log format is different than ice
,
the content model for the ice-events
element needs
to be modified to describe the markup of the content. To extend
the content-model for validation purposes, the ice-payload would
contain a DOCTYPE declaration that modifies the ENTITY declaration
that describes the content for the ice-events
element.
In the example below, the content-model is modified to use event
elements to wrap each log entry.
<!DOCTYPE ice-payload SYSTEM "ice.dtd" [ <!ENTITY % cm.events "event+" > <!ELEMENT event (#PCDATA) > ]> <ice-payload payload-id="ipl-80a56cfe-19980425-33" timestamp="25-04-1998T09:13:19" ice.version="1.0" > <ice-header> <ice-sender sender-id="http://www.eggnews.com/" name="Eggceptional News" role="syndicator" /> </ice-header> <ice-response response-id="irp-80425f38-19980621181600" > <ice-code numeric="200" phrase="OK" message-id="irq-80a56cfe-19980425011530" ></ice-code> <ice-events format="simple"> <event>something happened</event> <event>something else happened</event> </ice-events> </ice-response> </ice-payload>
Similar to using alternative markup for event log format, it
may be desirable to modify the content model used for an ice-item
.
The goal here is to allow validation of the content contained
within an ice-item
without changing any of the semantics
behind its handling. Thus, there is value to know that the XML
content distributed using the ICE protocol was packaged and delivered
in a valid well-formed way, but the management of the content
is no different than if it had been escaped for inclusion. In
the example below, the comic-strip
format is purely
fictional and is unknown to represent any work (present or future)
that may in fact resemble the format used therein. The mechanism
is the same as described in A.1, i.e., all declarations need to
be declared within the DOCTYPE declaration, but the content-model
being modified is for ice-item
.
<?xml version="1.0"?> <!DOCTYPE ice-payload SYSTEM "../ice.dtd" [ <!ENTITY % cm.item "comic-strip" > <!ELEMENT comic-strip (#PCDATA) > <!ATTLIST comic-strip author CDATA #REQUIRED copyright CDATA #REQUIRED pubdate CDATA #REQUIRED numpanes CDATA #IMPLIED title CDATA #REQUIRED > ]> <ice-payload ... <ice-response ... <ice-package ... <ice-item-group ... <ice-item item-id="431-1" subscription-element="431-1" name="Comic" content-filename="d.gif" content-type="application/xml" > <comic-strip title="Doones County" author="Gary Beathard" numpanes="3" copyright="United Tribune" pubdate="20010324"> PdXIWZQ8IiPLHtxqyjZFWt0hHrQcrjxAQ8VquFJS8vDC+ g4SsHSChBRUN0tTxS1wTuMC/242YYPBs87U8IkRlGu4G5 . . . M7qLNPuTNMlXc8G4sUgXc8dPdREbcFWnM9FndTgkwAAOw== </comic-strip> </ice-item> </ice-item-group> </ice-package> </ice-response> </ice-payload>
Replacing the content model for the ice-package
element provides a way to leverage ICE applications for managing
content segments from arbitrary XML markup. Besides the mechanisms
shown in the other sections where an element's content model is
replaced, replacing the content model for the ice-package
element requires that the attributes associated with the ice-item
element be applied to appropriate elements within the domain-specific
element declarations, otherwise, it is possible that the Subscriber's
ICE application will not have enough context to know how to manage
the delivered content.
There are some restrictions to be aware of when extending the
ice-package
content model.
<!ENTITY % cm.package "#PCDATA">
,
instead use elements in the content model such as that shown
in the sample below.
attlist.item
must be defined and
used as in the example.
name
attribute normally used on the ice-item
element is not needed because the domain-specific name is the
generic identifier associated with the element being used in
place of ice-item
.
ice-package
content model
being replaced (except ice-item-remove
is still
in effect). The content model can be augmented using an entity
declaration that instead looks like<!ENTITY
% cm.package "ice-item-group | ice-item | comic-strip |
ice-item-ref" >
ice-payload
.
<?xml version="1.0"?> <!DOCTYPE ice-payload SYSTEM "../ice.dtd" [ <!ENTITY % cm.package "(ice-item|comic-strip)+" > <!ELEMENT comic-strip (#PCDATA) > <!ATTLIST comic-strip author CDATA #REQUIRED copyright CDATA #REQUIRED pubdate CDATA #REQUIRED numpanes CDATA #IMPLIED title CDATA #REQUIRED > <!ENTITY % attlist.item " activation CDATA #IMPLIED expiration CDATA #IMPLIED content-filename CDATA #IMPLIED content-transfer-encoding (base64 | x-native-xml) 'x-native-xml' content-type CDATA 'application/octet-stream' ice-element CDATA #FIXED 'ice-item' ip-status CDATA #IMPLIED item-id CDATA #REQUIRED lang CDATA #IMPLIED license CDATA #IMPLIED rights-holder CDATA #IMPLIED show-credit CDATA #IMPLIED subscription-element CDATA #IMPLIED "> <!ATTLIST comic-strip %attlist.item; > ]> <ice-payload ... <ice-response ... <ice-package ... <comic-strip item-id="431-1" subscription-element="431-1" content-type="phrase/html" title="Doones County" author="Gary Beathard" numpanes="3" copyright="United Tribune" pubdate="20010324"> PdXIWZQ8IiPLHtxqyjZFWt0hHrQcrjxAQ8VquFJS8vDC+ g4SsHSChBRUN0tTxS1wTuMC/242YYPBs87U8IkRlGu4G5 . . . M7qLNPuTNMlXc8G4sUgXc8dPdREbcFWnM9FndTgkwAAOw== </comic-strip> </ice-package> </ice-response> </ice-payload>
<!ENTITY % cm.messages "ice-request+ | ice-response+ | ice-unsolicited-now | ice-unsolicited-request+ | ice-unsolicited-response+" > <!ELEMENT ice-payload (ice-header, (%cm.messages;)) > <!ATTLIST ice-payload ice.version CDATA #REQUIRED payload-id CDATA #REQUIRED timestamp CDATA #REQUIRED > <!ELEMENT ice-header (ice-sender, ice-receiver?, ice-user-agent?) > <!ELEMENT ice-sender EMPTY > <!ATTLIST ice-sender name CDATA #REQUIRED role (subscriber | syndicator) #REQUIRED sender-id CDATA #REQUIRED > <!ELEMENT ice-receiver EMPTY > <!ATTLIST ice-receiver name CDATA #REQUIRED receiver-id CDATA #REQUIRED > <!ELEMENT ice-user-agent (#PCDATA) > <!ELEMENT ice-code (#PCDATA) > <!ATTLIST ice-code message-id CDATA #IMPLIED numeric CDATA #REQUIRED package-id CDATA #IMPLIED payload-id CDATA #IMPLIED phrase CDATA #REQUIRED > <!-- ============================================================ --> <!-- Declaration of ICE requests. --> <!-- ============================================================ --> <!ENTITY % sub.requests "ice-cancel | ice-get-catalog | ice-get-package | ice-get-sequence | ice-offer | ice-repair-item" > <!ENTITY % syn.requests "ice-package+ | ice-send-confirmations" > <!ENTITY % com.requests "ice-change-subscription | ice-code | ice-get-event-log | ice-get-status | ice-nop | ice-notify" > <!ELEMENT ice-request (%sub.requests; | %syn.requests; | %com.requests;) > <!ATTLIST ice-request request-id CDATA #REQUIRED > <!ELEMENT ice-cancel EMPTY > <!ATTLIST ice-cancel lang CDATA #REQUIRED reason CDATA #REQUIRED subscription-id CDATA #REQUIRED > <!ELEMENT ice-change-subscription EMPTY > <!ATTLIST ice-change-subscription subscription-id CDATA #REQUIRED > <!-- ice-code defined above --> <!ELEMENT ice-get-catalog EMPTY > <!ELEMENT ice-get-events EMPTY > <!ATTLIST ice-get-events format CDATA #IMPLIED start CDATA #IMPLIED stop CDATA #IMPLIED subscription-id CDATA #IMPLIED > <!ELEMENT ice-get-package EMPTY > <!ATTLIST ice-get-package current-state CDATA #REQUIRED parameter CDATA #IMPLIED subscription-id CDATA #REQUIRED > <!ELEMENT ice-get-sequence (ice-package-state+) > <!ATTLIST ice-get-sequence current-state CDATA #REQUIRED subscription-id CDATA #REQUIRED > <!ELEMENT ice-package-state EMPTY > <!ATTLIST ice-package-state package-id CDATA #REQUIRED new-state CDATA #REQUIRED > <!ELEMENT ice-get-status EMPTY > <!ATTLIST ice-get-status subscription-id CDATA #IMPLIED > <!ELEMENT ice-nop EMPTY > <!ELEMENT ice-notify (ice-text+) > <!ATTLIST ice-notify priority (1 | 2 | 3 | 4 | 5) #REQUIRED > <!ELEMENT ice-text (#PCDATA) > <!ATTLIST ice-text lang CDATA #IMPLIED > <!-- ice-offer is declared below. --> <!-- ice-package is declared below --> <!ELEMENT ice-repair-item EMPTY > <!ATTLIST ice-repair-item current-state CDATA #REQUIRED subscription-element CDATA #REQUIRED subscription-id CDATA #REQUIRED > <!ELEMENT ice-send-confirmations EMPTY > <!ATTLIST ice-send-confirmations subscription-id CDATA #IMPLIED > <!-- ============================================================ --> <!-- Declaration of ICE responses. --> <!-- ============================================================ --> <!ENTITY % uni.responses "ice-cancellation | ice-catalog | ice-location | ice-offer | ice-package+ | ice-sequence | ice-subscription" > <!ENTITY % com.responses "ice-events | ice-status" > <!ELEMENT ice-response (ice-code, (%uni.responses; | %com.responses;)?) > <!ATTLIST ice-response response-id CDATA #REQUIRED unsolicited-pending (false | true) "false" > <!ELEMENT ice-cancellation EMPTY > <!ATTLIST ice-cancellation cancellation-id CDATA #REQUIRED subscription-id CDATA #REQUIRED > <!ELEMENT ice-catalog (ice-contact, (ice-offer-group | ice-offer)*) > <!ELEMENT ice-contact (ice-text+) > <!ATTLIST ice-contact description CDATA #REQUIRED lang CDATA #IMPLIED name CDATA #REQUIRED url CDATA #IMPLIED > <!ELEMENT ice-offer-group ((ice-offer-group | ice-offer)+) > <!ATTLIST ice-offer-group description CDATA #REQUIRED > <!-- ice-offer declared below --> <!ENTITY % cm.events "ice-event-log" > <!ELEMENT ice-events (%cm.events;) > <!ATTLIST ice-events format CDATA #REQUIRED start CDATA #IMPLIED stop CDATA #IMPLIED subscription-id CDATA #IMPLIED > <!ELEMENT ice-location EMPTY > <!ATTLIST ice-location url CDATA #REQUIRED > <!-- ice-offer is declared below. --> <!-- ice-package is declared below. --> <!ELEMENT ice-sequence (ice-package-state*) > <!ATTLIST ice-sequence subscription-id CDATA #REQUIRED > <!ELEMENT ice-status (ice-contact, ice-subscription+) > <!ELEMENT ice-subscription (ice-offer) > <!ATTLIST ice-subscription current-state CDATA #IMPLIED expiration-date CDATA #IMPLIED expiration-priority (first | last) #IMPLIED quantity-remaining CDATA #IMPLIED subscription-id CDATA #REQUIRED > <!-- ============================================================ --> <!-- Declaration of ICE unsolicited messages. --> <!-- ============================================================ --> <!ELEMENT ice-unsolicited-now EMPTY > <!ATTLIST ice-unsolicited-now request-id CDATA #REQUIRED > <!ELEMENT ice-unsolicited-request (%syn.requests; | %com.requests;) > <!ATTLIST ice-unsolicited-request unsolicited-request-id CDATA #REQUIRED > <!ELEMENT ice-unsolicited-response (ice-code, (%com.responses;)?) > <!ATTLIST ice-unsolicited-response unsolicited-response-id CDATA #REQUIRED > <!-- ============================================================ --> <!-- Declaration of ice-offer --> <!-- ============================================================ --> <!ELEMENT ice-offer (ice-delivery-policy, ice-business-term*) > <!ATTLIST ice-offer atomic-use (false | true) "false" constraints-hash CDATA #IMPLIED constraints-hash-method CDATA #IMPLIED constraints-url CDATA #IMPLIED description CDATA #REQUIRED editable (false | true) "false" ip-status CDATA #IMPLIED rights-holder CDATA #IMPLIED show-credit CDATA #IMPLIED subscription-id CDATA #IMPLIED usage-required (true | false) "false" > <!ELEMENT ice-business-term (ice-text+) > <!ATTLIST ice-business-term type (credit | licensing | payment | reporting) #REQUIRED url CDATA #IMPLIED > <!ELEMENT ice-delivery-policy (ice-delivery-rule+) > <!ATTLIST ice-delivery-policy startdate CDATA #IMPLIED stopdate CDATA #IMPLIED > <!ELEMENT ice-delivery-rule (ice-negotiable*) > <!ATTLIST ice-delivery-rule duration CDATA #IMPLIED maxcount CDATA #IMPLIED maxfreq CDATA #IMPLIED mincount CDATA #IMPLIED minfreq CDATA #IMPLIED mode (push | pull) #REQUIRED monthday NMTOKENS #IMPLIED startdate CDATA #IMPLIED starttime CDATA #IMPLIED stopdate CDATA #IMPLIED url CDATA #IMPLIED weekday NMTOKENS #IMPLIED > <!ELEMENT ice-negotiable EMPTY > <!ATTLIST ice-negotiable max CDATA #IMPLIED min CDATA #IMPLIED type (duration | maxcount | maxfreq | mincount | minfreq | monthday | startdate | starttime | stopdate | weekday) #REQUIRED > <!-- ============================================================ --> <!-- Declaration of ice-package --> <!-- ============================================================ --> <!ENTITY % cm.package "ice-item-group | ice-item | ice-item-ref" > <!ELEMENT ice-package ((ice-item-remove+, (%cm.package;)*) | (%cm.package;)+) > <!ATTLIST ice-package activation CDATA #IMPLIED atomic-use (false | true) "false" confirmation (false | true) "false" editable (false | true) "false" exclusion CDATA #IMPLIED expiration CDATA #IMPLIED fullupdate (false | true) "false" ip-status CDATA #IMPLIED lang CDATA #IMPLIED license CDATA #IMPLIED new-state CDATA #REQUIRED old-state CDATA #REQUIRED package-id CDATA #REQUIRED item-repair (false | true) "false" rights-holder CDATA #IMPLIED show-credit CDATA #IMPLIED subscription-id CDATA #REQUIRED > <!ELEMENT ice-item-remove EMPTY > <!ATTLIST ice-item-remove subscription-element CDATA #REQUIRED > <!ELEMENT ice-item-group ((%cm.package;)+) > <!ATTLIST ice-item-group activation CDATA #IMPLIED expiration CDATA #IMPLIED ip-status CDATA #IMPLIED item-group-id CDATA #REQUIRED lang CDATA #IMPLIED license CDATA #IMPLIED name CDATA #IMPLIED rights-holder CDATA #IMPLIED show-credit CDATA #IMPLIED subscription-element CDATA #IMPLIED > <!ENTITY % cm.item "#PCDATA" > <!ELEMENT ice-item (%cm.item;) > <!ENTITY % attlist.item " activation CDATA #IMPLIED expiration CDATA #IMPLIED content-filename CDATA #IMPLIED content-transfer-encoding (base64 | x-native-xml) 'x-native-xml' content-type CDATA 'application/octet-stream' ice-element CDATA #FIXED 'ice-item' ip-status CDATA #IMPLIED item-id CDATA #REQUIRED lang CDATA #IMPLIED license CDATA #IMPLIED rights-holder CDATA #IMPLIED show-credit CDATA #IMPLIED subscription-element CDATA #IMPLIED "> <!ATTLIST ice-item %attlist.item; > <!ATTLIST ice-item name CDATA #REQUIRED > <!ELEMENT ice-item-ref EMPTY > <!ATTLIST ice-item-ref activation CDATA #IMPLIED content-filename CDATA #IMPLIED expiration CDATA #IMPLIED ip-status CDATA #IMPLIED item-id CDATA #REQUIRED license CDATA #IMPLIED name CDATA #REQUIRED rights-holder CDATA #IMPLIED show-credit CDATA #IMPLIED subscription-element CDATA #IMPLIED url CDATA #REQUIRED > <!-- ============================================================ --> <!-- Declaration of default ice-event-log --> <!-- ============================================================ --> <!ELEMENT ice-event-log ((ice-event-msg | ice-event-info)*) > <!ATTLIST ice-event-log version CDATA #REQUIRED > <!ELEMENT ice-event-msg (ice-code?, ice-event-data?) > <!ATTLIST ice-event-msg other-id CDATA #IMPLIED request CDATA #REQUIRED request-id CDATA #REQUIRED request-start CDATA #REQUIRED request-type CDATA #IMPLIED response CDATA #REQUIRED response-id CDATA #IMPLIED response-stop CDATA #REQUIRED response-type CDATA #IMPLIED role (requestor | responder) #REQUIRED subscription-id CDATA #IMPLIED > <!ELEMENT ice-event-info (ice-event-data?) > <!ATTLIST ice-event-info event CDATA #REQUIRED event-start CDATA #REQUIRED event-stop CDATA #REQUIRED > <!ELEMENT ice-event-data ANY >