| <?xml version = "1.0"?> |
| |
| <!-- |
| EDITORS: (PH) Pieter Hintjens <ph@imatix.com> |
| (KvdR) Kim van der Riet <kim.vdriet@redhat.com> |
| |
| These editors have been assigned by the AMQP working group. |
| Please do not edit/commit this file without consulting with |
| one of the above editors. |
| ======================================================== |
| |
| TODOs |
| - see TODO comments in the text |
| --> |
| |
| <!-- |
| Copyright Notice |
| ================ |
| (c) Copyright JPMorgan Chase Bank & Co., Cisco Systems, Inc., Envoy Technologies Inc., |
| iMatix Corporation, IONA\ufffd Technologies, Red Hat, Inc., |
| TWIST Process Innovations, and 29West Inc. 2006. All rights reserved. |
| |
| License |
| ======= |
| JPMorgan Chase Bank & Co., Cisco Systems, Inc., Envoy Technologies Inc., iMatix |
| Corporation, IONA\ufffd Technologies, Red Hat, Inc., TWIST Process Innovations, and |
| 29West Inc. (collectively, the "Authors") each hereby grants to you a worldwide, |
| perpetual, royalty-free, nontransferable, nonexclusive license to |
| (i) copy, display, and implement the Advanced Messaging Queue Protocol |
| ("AMQP") Specification and (ii) the Licensed Claims that are held by |
| the Authors, all for the purpose of implementing the Advanced Messaging |
| Queue Protocol Specification. Your license and any rights under this |
| Agreement will terminate immediately without notice from |
| any Author if you bring any claim, suit, demand, or action related to |
| the Advanced Messaging Queue Protocol Specification against any Author. |
| Upon termination, you shall destroy all copies of the Advanced Messaging |
| Queue Protocol Specification in your possession or control. |
| |
| As used hereunder, "Licensed Claims" means those claims of a patent or |
| patent application, throughout the world, excluding design patents and |
| design registrations, owned or controlled, or that can be sublicensed |
| without fee and in compliance with the requirements of this |
| Agreement, by an Author or its affiliates now or at any |
| future time and which would necessarily be infringed by implementation |
| of the Advanced Messaging Queue Protocol Specification. A claim is |
| necessarily infringed hereunder only when it is not possible to avoid |
| infringing it because there is no plausible non-infringing alternative |
| for implementing the required portions of the Advanced Messaging Queue |
| Protocol Specification. Notwithstanding the foregoing, Licensed Claims |
| shall not include any claims other than as set forth above even if |
| contained in the same patent as Licensed Claims; or that read solely |
| on any implementations of any portion of the Advanced Messaging Queue |
| Protocol Specification that are not required by the Advanced Messaging |
| Queue Protocol Specification, or that, if licensed, would require a |
| payment of royalties by the licensor to unaffiliated third parties. |
| Moreover, Licensed Claims shall not include (i) any enabling technologies |
| that may be necessary to make or use any Licensed Product but are not |
| themselves expressly set forth in the Advanced Messaging Queue Protocol |
| Specification (e.g., semiconductor manufacturing technology, compiler |
| technology, object oriented technology, networking technology, operating |
| system technology, and the like); or (ii) the implementation of other |
| published standards developed elsewhere and merely referred to in the |
| body of the Advanced Messaging Queue Protocol Specification, or |
| (iii) any Licensed Product and any combinations thereof the purpose or |
| function of which is not required for compliance with the Advanced |
| Messaging Queue Protocol Specification. For purposes of this definition, |
| the Advanced Messaging Queue Protocol Specification shall be deemed to |
| include both architectural and interconnection requirements essential |
| for interoperability and may also include supporting source code artifacts |
| where such architectural, interconnection requirements and source code |
| artifacts are expressly identified as being required or documentation to |
| achieve compliance with the Advanced Messaging Queue Protocol Specification. |
| |
| As used hereunder, "Licensed Products" means only those specific portions |
| of products (hardware, software or combinations thereof) that implement |
| and are compliant with all relevant portions of the Advanced Messaging |
| Queue Protocol Specification. |
| |
| The following disclaimers, which you hereby also acknowledge as to any |
| use you may make of the Advanced Messaging Queue Protocol Specification: |
| |
| THE ADVANCED MESSAGING QUEUE PROTOCOL SPECIFICATION IS PROVIDED "AS IS," |
| AND THE AUTHORS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR |
| IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, |
| FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE |
| CONTENTS OF THE ADVANCED MESSAGING QUEUE PROTOCOL SPECIFICATION ARE |
| SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF THE ADVANCED |
| MESSAGING QUEUE PROTOCOL SPECIFICATION WILL NOT INFRINGE ANY THIRD PARTY |
| PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. |
| |
| THE AUTHORS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, |
| INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING TO ANY |
| USE, IMPLEMENTATION OR DISTRIBUTION OF THE ADVANCED MESSAGING QUEUE |
| PROTOCOL SPECIFICATION. |
| |
| The name and trademarks of the Authors may NOT be used in any manner, |
| including advertising or publicity pertaining to the Advanced Messaging |
| Queue Protocol Specification or its contents without specific, written |
| prior permission. Title to copyright in the Advanced Messaging Queue |
| Protocol Specification will at all times remain with the Authors. |
| |
| No other rights are granted by implication, estoppel or otherwise. |
| |
| Upon termination of your license or rights under this Agreement, you |
| shall destroy all copies of the Advanced Messaging Queue Protocol |
| Specification in your possession or control. |
| |
| Trademarks |
| ========== |
| "JPMorgan", "JPMorgan Chase", "Chase", the JPMorgan Chase logo and the |
| Octagon Symbol are trademarks of JPMorgan Chase & Co. |
| |
| IMATIX and the iMatix logo are trademarks of iMatix Corporation sprl. |
| |
| IONA, IONA Technologies, and the IONA logos are trademarks of IONA |
| Technologies PLC and/or its subsidiaries. |
| |
| LINUX is a trademark of Linus Torvalds. RED HAT and JBOSS are registered |
| trademarks of Red Hat, Inc. in the US and other countries. |
| |
| Java, all Java-based trademarks and OpenOffice.org are trademarks of |
| Sun Microsystems, Inc. in the United States, other countries, or both. |
| |
| Other company, product, or service names may be trademarks or service |
| marks of others. |
| |
| Links to full AMQP specification: |
| ================================= |
| http://www.envoytech.org/spec/amq/ |
| http://www.iona.com/opensource/amqp/ |
| http://www.redhat.com/solutions/specifications/amqp/ |
| http://www.twiststandards.org/tiki-index.php?page=AMQ |
| http://www.imatix.com/amqp |
| --> |
| |
| <!-- |
| <!DOCTYPE amqp SYSTEM "amqp.dtd"> |
| --> |
| |
| <!-- XML Notes |
| |
| We use entities to indicate repetition; attributes to indicate properties. |
| |
| We use the 'name' attribute as an identifier, usually within the context |
| of the surrounding entities. |
| |
| We use spaces to seperate words in names, so that we can print names in |
| their natural form depending on the context - underlines for source code, |
| hyphens for written text, etc. |
| |
| We do not enforce any particular validation mechanism but we support all |
| mechanisms. The protocol definition conforms to a formal grammar that is |
| published seperately in several technologies. |
| |
| --> |
| |
| <amqp major = "0" minor = "10" port = "5672" comment = "AMQ Protocol"> |
| <!-- |
| ====================================================== |
| == CONSTANTS |
| ====================================================== |
| --> |
| <!-- Frame types --> |
| <constant name = "frame-method" value = "1" /> |
| <constant name = "frame-header" value = "2" /> |
| <constant name = "frame-body" value = "3" /> |
| <constant name = "frame-oob-method" value = "4" /> |
| <constant name = "frame-oob-header" value = "5" /> |
| <constant name = "frame-oob-body" value = "6" /> |
| <constant name = "frame-trace" value = "7" /> |
| <constant name = "frame-heartbeat" value = "8" /> |
| |
| <!-- Protocol constants --> |
| <constant name = "frame-min-size" value = "4096" /> |
| <constant name = "frame-end" value = "206" /> |
| |
| <!-- Reply codes --> |
| <constant name = "reply-success" value = "200"> |
| <doc> |
| Indicates that the method completed successfully. This reply code is |
| reserved for future use - the current protocol design does not use positive |
| confirmation and reply codes are sent only in case of an error. |
| </doc> |
| </constant> |
| |
| <constant name = "not-delivered" value = "310" class = "soft-error"> |
| <doc> |
| The client asked for a specific message that is no longer available. |
| The message was delivered to another client, or was purged from the queue |
| for some other reason. |
| </doc> |
| </constant> |
| |
| <constant name = "content-too-large" value = "311" class = "soft-error"> |
| <doc> |
| The client attempted to transfer content larger than the server could accept |
| at the present time. The client may retry at a later time. |
| </doc> |
| </constant> |
| |
| <constant name = "connection-forced" value = "320" class = "hard-error"> |
| <doc> |
| An operator intervened to close the connection for some reason. The client |
| may retry at some later date. |
| </doc> |
| </constant> |
| |
| <constant name = "invalid-path" value = "402" class = "hard-error"> |
| <doc> |
| The client tried to work with an unknown virtual host. |
| </doc> |
| </constant> |
| |
| <constant name = "access-refused" value = "403" class = "soft-error"> |
| <doc> |
| The client attempted to work with a server entity to which it has no |
| access due to security settings. |
| </doc> |
| </constant> |
| |
| <constant name = "not-found" value = "404" class = "soft-error"> |
| <doc>The client attempted to work with a server entity that does not exist.</doc> |
| </constant> |
| |
| <constant name = "resource-locked" value = "405" class = "soft-error"> |
| <doc> |
| The client attempted to work with a server entity to which it has no |
| access because another client is working with it. |
| </doc> |
| </constant> |
| |
| <constant name = "precondition-failed" value = "406" class = "soft-error"> |
| <doc> |
| The client requested a method that was not allowed because some precondition |
| failed. |
| </doc> |
| </constant> |
| |
| <constant name = "frame-error" value = "501" class = "hard-error"> |
| <doc> |
| The client sent a malformed frame that the server could not decode. This |
| strongly implies a programming error in the client. |
| </doc> |
| </constant> |
| |
| <constant name = "syntax-error" value = "502" class = "hard-error"> |
| <doc> |
| The client sent a frame that contained illegal values for one or more |
| fields. This strongly implies a programming error in the client. |
| </doc> |
| </constant> |
| |
| <constant name = "command-invalid" value = "503" class = "hard-error"> |
| <doc> |
| The client sent an invalid sequence of frames, attempting to perform an |
| operation that was considered invalid by the server. This usually implies |
| a programming error in the client. |
| </doc> |
| </constant> |
| |
| <constant name = "channel-error" value = "504" class = "hard-error"> |
| <doc> |
| The client attempted to work with a channel that had not been correctly |
| opened. This most likely indicates a fault in the client layer. |
| </doc> |
| </constant> |
| |
| <constant name = "resource-error" value = "506" class = "hard-error"> |
| <doc> |
| The server could not complete the method because it lacked sufficient |
| resources. This may be due to the client creating too many of some type |
| of entity. |
| </doc> |
| </constant> |
| |
| <constant name = "not-allowed" value = "530" class = "hard-error"> |
| <doc> |
| The client tried to work with some entity in a manner that is prohibited |
| by the server, due to security settings or by some other criteria. |
| </doc> |
| </constant> |
| |
| <constant name = "not-implemented" value = "540" class = "hard-error"> |
| <doc> |
| The client tried to use functionality that is not implemented in the |
| server. |
| </doc> |
| </constant> |
| |
| <constant name = "internal-error" value = "545" class = "hard-error"> |
| <doc> |
| The server could not complete the method because of an internal error. |
| The server may require intervention by an operator in order to resume |
| normal operations. |
| </doc> |
| </constant> |
| |
| <constant name = "test-double" value = "3.141592654"/> |
| <constant name = "test-str1" value = "hello, world!"/> |
| <constant name = "test-str2" value = "1.2.3.4"/> |
| |
| <!-- |
| ====================================================== |
| == DOMAIN TYPES |
| ====================================================== |
| --> |
| |
| <domain name = "access-ticket" type = "short" label = "access ticket granted by server"> |
| <doc> |
| An access ticket granted by the server for a certain set of access rights |
| within a specific realm. Access tickets are valid within the channel where |
| they were created, and expire when the channel closes. |
| </doc> |
| <assert check = "ne" value = "0" /> |
| </domain> |
| |
| <domain name = "class-id" type = "short" /> |
| |
| <domain name = "consumer-tag" type = "shortstr" label = "consumer tag"> |
| <doc> |
| Identifier for the consumer, valid within the current connection. |
| </doc> |
| </domain> |
| |
| <domain name = "delivery-tag" type = "longlong" label = "server-assigned delivery tag"> |
| <doc> |
| The server-assigned and channel-specific delivery tag |
| </doc> |
| <rule name = "channel-local"> |
| <doc> |
| The delivery tag is valid only within the channel from which the message was |
| received. I.e. a client MUST NOT receive a message on one channel and then |
| acknowledge it on another. |
| </doc> |
| </rule> |
| <rule name = "non-zero"> |
| <doc> |
| The server MUST NOT use a zero value for delivery tags. Zero is reserved |
| for client use, meaning "all messages so far received". |
| </doc> |
| </rule> |
| </domain> |
| |
| <domain name = "exchange-name" type = "shortstr" label = "exchange name"> |
| <doc> |
| The exchange name is a client-selected string that identifies the exchange for publish |
| methods. Exchange names may consist of any mixture of digits, letters, and underscores. |
| Exchange names are scoped by the virtual host. |
| </doc> |
| <assert check = "length" value = "127" /> |
| </domain> |
| |
| <domain name = "known-hosts" type = "shortstr" label = "list of known hosts"> |
| <doc> |
| Specifies the list of equivalent or alternative hosts that the server knows about, |
| which will normally include the current server itself. Clients can cache this |
| information and use it when reconnecting to a server after a failure. This field |
| may be empty. |
| </doc> |
| </domain> |
| |
| <domain name = "method-id" type = "long" /> |
| |
| <domain name = "no-ack" type = "bit" label = "no acknowledgement needed"> |
| <doc> |
| If this field is set the server does not expect acknowledgments for |
| messages. That is, when a message is delivered to the client the server |
| automatically and silently acknowledges it on behalf of the client. This |
| functionality increases performance but at the cost of reliability. |
| Messages can get lost if a client dies before it can deliver them to the |
| application. |
| </doc> |
| </domain> |
| |
| <domain name = "no-local" type = "bit" label = "do not deliver own messages"> |
| <doc> |
| If the no-local field is set the server will not send messages to the client that |
| published them. |
| </doc> |
| </domain> |
| |
| <domain name = "path" type = "shortstr"> |
| <doc> |
| Must start with a slash "/" and continue with path names separated by slashes. A path |
| name consists of any combination of at least one of [A-Za-z0-9] plus zero or more of |
| [.-_+!=:]. |
| </doc> |
| |
| <assert check = "notnull" /> |
| <assert check = "syntax" rule = "path" /> |
| <assert check = "length" value = "127" /> |
| </domain> |
| |
| <domain name = "peer-properties" type = "table"> |
| <doc> |
| This string provides a set of peer properties, used for identification, debugging, and |
| general information. |
| </doc> |
| </domain> |
| |
| <domain name = "queue-name" type = "shortstr" label = "queue name"> |
| <doc> |
| The queue name identifies the queue within the vhost. Queue names may consist of any |
| mixture of digits, letters, and underscores. |
| </doc> |
| <assert check = "length" value = "127" /> |
| </domain> |
| |
| <domain name = "redelivered" type = "bit" label = "message is being redelivered"> |
| <doc> |
| This indicates that the message has been previously delivered to this or |
| another client. |
| </doc> |
| <rule name = "implementation"> |
| <doc> |
| The server SHOULD try to signal redelivered messages when it can. When |
| redelivering a message that was not successfully acknowledged, the server |
| SHOULD deliver it to the original client if possible. |
| </doc> |
| <doc type = "scenario"> |
| Create a shared queue and publish a message to the queue. Consume the |
| message using explicit acknowledgements, but do not acknowledge the |
| message. Close the connection, reconnect, and consume from the queue |
| again. The message should arrive with the redelivered flag set. |
| </doc> |
| </rule> |
| <rule name = "hinting"> |
| <doc> |
| The client MUST NOT rely on the redelivered field but should take it as a |
| hint that the message may already have been processed. A fully robust |
| client must be able to track duplicate received messages on non-transacted, |
| and locally-transacted channels. |
| </doc> |
| </rule> |
| </domain> |
| |
| <domain name = "reply-code" type = "short" label = "reply code from server"> |
| <doc> |
| The reply code. The AMQ reply codes are defined as constants at the start |
| of this formal specification. |
| </doc> |
| <assert check = "notnull" /> |
| </domain> |
| |
| <domain name = "reply-text" type = "shortstr" label = "localised reply text"> |
| <doc> |
| The localised reply text. This text can be logged as an aid to resolving |
| issues. |
| </doc> |
| <assert check = "notnull" /> |
| </domain> |
| |
| <!-- Elementary domains --> |
| <domain name = "bit" type = "bit" label = "single bit" /> |
| <domain name = "octet" type = "octet" label = "single octet" /> |
| <domain name = "short" type = "short" label = "16-bit integer" /> |
| <domain name = "long" type = "long" label = "32-bit integer" /> |
| <domain name = "longlong" type = "longlong" label = "64-bit integer" /> |
| <domain name = "shortstr" type = "shortstr" label = "short string" /> |
| <domain name = "longstr" type = "longstr" label = "long string" /> |
| <domain name = "timestamp" type = "timestamp" label = "64-bit timestamp" /> |
| <domain name = "table" type = "table" label = "field table" /> |
| |
| <!-- == CONNECTION ======================================================= --> |
| |
| <!-- TODO 0.81 - the 'handler' attribute of methods needs to be reviewed, and if |
| no current implementations use it, removed. /PH 2006/07/20 |
| --> |
| |
| <class name = "connection" handler = "connection" index = "10" label = "work with socket connections"> |
| <doc> |
| The connection class provides methods for a client to establish a network connection to |
| a server, and for both peers to operate the connection thereafter. |
| </doc> |
| |
| <doc type = "grammar"> |
| connection = open-connection *use-connection close-connection |
| open-connection = C:protocol-header |
| S:START C:START-OK |
| *challenge |
| S:TUNE C:TUNE-OK |
| C:OPEN S:OPEN-OK | S:REDIRECT |
| challenge = S:SECURE C:SECURE-OK |
| use-connection = *channel |
| close-connection = C:CLOSE S:CLOSE-OK |
| / S:CLOSE C:CLOSE-OK |
| </doc> |
| |
| <chassis name = "server" implement = "MUST" /> |
| <chassis name = "client" implement = "MUST" /> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "start" synchronous = "1" index = "10" label = "start connection negotiation"> |
| <doc> |
| This method starts the connection negotiation process by telling the client the |
| protocol version that the server proposes, along with a list of security mechanisms |
| which the client can use for authentication. |
| </doc> |
| |
| <rule name = "protocol-name"> |
| <doc> |
| If the server cannot support the protocol specified in the protocol header, |
| it MUST close the socket connection without sending any response method. |
| </doc> |
| <doc type = "scenario"> |
| The client sends a protocol header containing an invalid protocol name. |
| The server must respond by closing the connection. |
| </doc> |
| </rule> |
| <rule name = "server-support"> |
| <doc> |
| The server MUST provide a protocol version that is lower than or equal to |
| that requested by the client in the protocol header. |
| </doc> |
| <doc type = "scenario"> |
| The client requests a protocol version that is higher than any valid |
| implementation, e.g. 9.0. The server must respond with a current |
| protocol version, e.g. 1.0. |
| </doc> |
| </rule> |
| <rule name = "client-support"> |
| <doc> |
| If the client cannot handle the protocol version suggested by the server |
| it MUST close the socket connection. |
| </doc> |
| <doc type = "scenario"> |
| The server sends a protocol version that is lower than any valid |
| implementation, e.g. 0.1. The client must respond by closing the |
| connection. |
| </doc> |
| </rule> |
| |
| <chassis name = "client" implement = "MUST" /> |
| <response name = "start-ok" /> |
| |
| <field name = "version-major" domain = "octet" label = "protocol major version"> |
| <doc> |
| The version of the protocol, expressed in protocol units of 0.1 public |
| versions and properly printed as two digits with a leading zero. I.e. a |
| protocol version of "09" represents a public version "0.9". The decimal |
| shift allows the correct expression of pre-1.0 protocol releases. |
| </doc> |
| <doc type = "todo"> |
| This field should be renamed to "protocol version". |
| </doc> |
| </field> |
| |
| <field name = "version-minor" domain = "octet" label = "protocol major version"> |
| <doc> |
| The protocol revision, expressed as an integer from 0 to 9. The use of more |
| than ten revisions is discouraged. The public version string is constructed |
| from the protocol version and revision as follows: we print the protocol |
| version with one decimal position, and we append the protocol revision. A |
| version=10 and revision=2 are printed as "1.02". |
| </doc> |
| <doc type = "todo"> |
| This field should be renamed to "protocol revision". |
| </doc> |
| </field> |
| |
| <field name = "server-properties" domain = "peer-properties" label = "server properties"> |
| <rule name = "required-fields"> |
| <doc> |
| The properties SHOULD contain at least these fields: "host", specifying the |
| server host name or address, "product", giving the name of the server product, |
| "version", giving the name of the server version, "platform", giving the name |
| of the operating system, "copyright", if appropriate, and "information", giving |
| other general information. |
| </doc> |
| <doc type = "scenario"> |
| Client connects to server and inspects the server properties. It checks for |
| the presence of the required fields. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "mechanisms" domain = "longstr" label = "available security mechanisms"> |
| <doc> |
| A list of the security mechanisms that the server supports, delimited by spaces. |
| Currently ASL supports these mechanisms: PLAIN. |
| </doc> |
| <assert check = "notnull" /> |
| </field> |
| |
| <field name = "locales" domain = "longstr" label = "available message locales"> |
| <doc> |
| A list of the message locales that the server supports, delimited by spaces. The |
| locale defines the language in which the server will send reply texts. |
| </doc> |
| <rule name = "required-support"> |
| <doc> |
| The server MUST support at least the en_US locale. |
| </doc> |
| <doc type = "scenario"> |
| Client connects to server and inspects the locales field. It checks for |
| the presence of the required locale(s). |
| </doc> |
| </rule> |
| <assert check = "notnull" /> |
| </field> |
| </method> |
| |
| <method name = "start-ok" synchronous = "1" index = "11" |
| label = "select security mechanism and locale"> |
| <doc> |
| This method selects a SASL security mechanism. ASL uses SASL (RFC2222) to |
| negotiate authentication and encryption. |
| </doc> |
| |
| <chassis name = "server" implement = "MUST" /> |
| |
| <field name = "client-properties" domain = "peer-properties" label = "client properties"> |
| <rule name = "required-fields"> |
| <!-- This rule is not testable from the client side --> |
| <doc> |
| The properties SHOULD contain at least these fields: "product", giving the name |
| of the client product, "version", giving the name of the client version, "platform", |
| giving the name of the operating system, "copyright", if appropriate, and |
| "information", giving other general information. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "mechanism" domain = "shortstr" label = "selected security mechanism"> |
| <doc> |
| A single security mechanisms selected by the client, which must be one of those |
| specified by the server. |
| </doc> |
| <rule name = "security"> |
| <doc> |
| The client SHOULD authenticate using the highest-level security profile it |
| can handle from the list provided by the server. |
| </doc> |
| </rule> |
| <rule name = "validity"> |
| <doc> |
| If the mechanism field does not contain one of the security mechanisms |
| proposed by the server in the Start method, the server MUST close the |
| connection without sending any further data. |
| </doc> |
| <doc type = "scenario"> |
| Client connects to server and sends an invalid security mechanism. The |
| server must respond by closing the connection (a socket close, with no |
| connection close negotiation). |
| </doc> |
| </rule> |
| <assert check = "notnull" /> |
| </field> |
| |
| <field name = "response" domain = "longstr" label = "security response data"> |
| <doc> |
| A block of opaque data passed to the security mechanism. The contents of this |
| data are defined by the SASL security mechanism. |
| </doc> |
| <assert check = "notnull" /> |
| </field> |
| |
| <field name = "locale" domain = "shortstr" label = "selected message locale"> |
| <doc> |
| A single message local selected by the client, which must be one of those |
| specified by the server. |
| </doc> |
| <assert check = "notnull" /> |
| </field> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "secure" synchronous = "1" index = "20" label = "security mechanism challenge"> |
| <doc> |
| The SASL protocol works by exchanging challenges and responses until both peers have |
| received sufficient information to authenticate each other. This method challenges |
| the client to provide more information. |
| </doc> |
| |
| <chassis name = "client" implement = "MUST" /> |
| <response name = "secure-ok" /> |
| |
| <field name = "challenge" domain = "longstr" label = "security challenge data"> |
| <doc> |
| Challenge information, a block of opaque binary data passed to the security |
| mechanism. |
| </doc> |
| </field> |
| </method> |
| |
| <method name = "secure-ok" synchronous = "1" index = "21" label = "security mechanism response"> |
| <doc> |
| This method attempts to authenticate, passing a block of SASL data for the security |
| mechanism at the server side. |
| </doc> |
| |
| <chassis name = "server" implement = "MUST" /> |
| |
| <field name = "response" domain = "longstr" label = "security response data"> |
| <doc> |
| A block of opaque data passed to the security mechanism. The contents of this |
| data are defined by the SASL security mechanism. |
| </doc> |
| <assert check = "notnull" /> |
| </field> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "tune" synchronous = "1" index = "30" |
| label = "propose connection tuning parameters"> |
| <doc> |
| This method proposes a set of connection configuration values to the client. The |
| client can accept and/or adjust these. |
| </doc> |
| |
| <chassis name = "client" implement = "MUST" /> |
| |
| <response name = "tune-ok" /> |
| |
| <field name = "channel-max" domain = "short" label = "proposed maximum channels"> |
| <doc> |
| The maximum total number of channels that the server allows per connection. Zero |
| means that the server does not impose a fixed limit, but the number of allowed |
| channels may be limited by available server resources. |
| </doc> |
| </field> |
| |
| <field name = "frame-max" domain = "long" label = "proposed maximum frame size"> |
| <doc> |
| The largest frame size that the server proposes for the connection. The client |
| can negotiate a lower value. Zero means that the server does not impose any |
| specific limit but may reject very large frames if it cannot allocate resources |
| for them. |
| </doc> |
| <rule name = "minimum"> |
| <doc> |
| Until the frame-max has been negotiated, both peers MUST accept frames of up |
| to frame-min-size octets large, and the minimum negotiated value for frame-max |
| is also frame-min-size. |
| </doc> |
| <doc type = "scenario"> |
| Client connects to server and sends a large properties field, creating a frame |
| of frame-min-size octets. The server must accept this frame. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "heartbeat" domain = "short" label = "desired heartbeat delay"> |
| <!-- TODO 0.82 - the heartbeat negotiation mechanism was changed during |
| implementation because the model documented here does not actually |
| work properly. The best model we found is that the server proposes |
| a heartbeat value to the client; the client can reply with zero, meaning |
| 'do not use heartbeats (as documented here), or can propose its own |
| heartbeat value, which the server should then accept. This is different |
| from the model here which is disconnected - e.g. each side requests a |
| heartbeat independently. Basically a connection is heartbeated in |
| both ways, or not at all, depending on whether both peers support |
| heartbeating or not, and the heartbeat value should itself be chosen |
| by the client so that remote links can get a higher value. Also, the |
| actual heartbeat mechanism needs documentation, and is as follows: so |
| long as there is activity on a connection - in or out - both peers |
| assume the connection is active. When there is no activity, each peer |
| must send heartbeat frames. When no heartbeat frame is received after |
| N cycles (where N is at least 2), the connection can be considered to |
| have died. /PH 2006/07/19 |
| --> |
| <doc> |
| The delay, in seconds, of the connection heartbeat that the server wants. |
| Zero means the server does not want a heartbeat. |
| </doc> |
| </field> |
| </method> |
| |
| <method name = "tune-ok" synchronous = "1" index = "31" |
| label = "negotiate connection tuning parameters"> |
| <doc> |
| This method sends the client's connection tuning parameters to the server. |
| Certain fields are negotiated, others provide capability information. |
| </doc> |
| |
| <chassis name = "server" implement = "MUST" /> |
| |
| <field name = "channel-max" domain = "short" label = "negotiated maximum channels"> |
| <doc> |
| The maximum total number of channels that the client will use per connection. |
| </doc> |
| <rule name = "upper-limit"> |
| <doc> |
| If the client specifies a channel max that is higher than the value provided |
| by the server, the server MUST close the connection without attempting a |
| negotiated close. The server may report the error in some fashion to assist |
| implementors. |
| </doc> |
| </rule> |
| <assert check = "notnull" /> |
| <assert check = "le" method = "tune" field = "channel-max" /> |
| </field> |
| |
| <field name = "frame-max" domain = "long" label = "negotiated maximum frame size"> |
| <doc> |
| The largest frame size that the client and server will use for the connection. |
| Zero means that the client does not impose any specific limit but may reject |
| very large frames if it cannot allocate resources for them. Note that the |
| frame-max limit applies principally to content frames, where large contents can |
| be broken into frames of arbitrary size. |
| </doc> |
| <rule name = "minimum"> |
| <doc> |
| Until the frame-max has been negotiated, both peers MUST accept frames of up |
| to frame-min-size octets large, and the minimum negotiated value for frame-max |
| is also frame-min-size. |
| </doc> |
| </rule> |
| <rule name = "upper-limit"> |
| <doc> |
| If the client specifies a frame max that is higher than the value provided |
| by the server, the server MUST close the connection without attempting a |
| negotiated close. The server may report the error in some fashion to assist |
| implementors. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "heartbeat" domain = "short" label = "desired heartbeat delay"> |
| <doc> |
| The delay, in seconds, of the connection heartbeat that the client wants. Zero |
| means the client does not want a heartbeat. |
| </doc> |
| </field> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "open" synchronous = "1" index = "40" label = "open connection to virtual host"> |
| <doc> |
| This method opens a connection to a virtual host, which is a collection of |
| resources, and acts to separate multiple application domains within a server. |
| The server may apply arbitrary limits per virtual host, such as the number |
| of each type of entity that may be used, per connection and/or in total. |
| </doc> |
| |
| <chassis name = "server" implement = "MUST" /> |
| <response name = "open-ok" /> |
| <response name = "redirect" /> |
| |
| <field name = "virtual-host" domain = "path" label = "virtual host name"> |
| <!-- TODO 0.82 - the entire vhost model needs review. This concept was |
| prompted by the HTTP vhost concept but does not fit very well into |
| AMQP. Currently we use the vhost as a "cluster identifier" which is |
| inaccurate usage. /PH 2006/07/19 |
| --> |
| <assert check = "regexp" value = "^[a-zA-Z0-9/-_]+$" /> |
| <doc> |
| The name of the virtual host to work with. |
| </doc> |
| <rule name = "separation"> |
| <doc> |
| If the server supports multiple virtual hosts, it MUST enforce a full |
| separation of exchanges, queues, and all associated entities per virtual |
| host. An application, connected to a specific virtual host, MUST NOT be able |
| to access resources of another virtual host. |
| </doc> |
| </rule> |
| <rule name = "security"> |
| <doc> |
| The server SHOULD verify that the client has permission to access the |
| specified virtual host. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "capabilities" domain = "shortstr" label = "required capabilities"> |
| <doc> |
| The client can specify zero or more capability names, delimited by spaces. |
| The server can use this string to how to process the client's connection |
| request. |
| </doc> |
| </field> |
| |
| <field name = "insist" domain = "bit" label = "insist on connecting to server"> |
| <doc> |
| In a configuration with multiple collaborating servers, the server may respond |
| to a Connection.Open method with a Connection.Redirect. The insist option tells |
| the server that the client is insisting on a connection to the specified server. |
| </doc> |
| <rule name = "behaviour"> |
| <doc> |
| When the client uses the insist option, the server MUST NOT respond with a |
| Connection.Redirect method. If it cannot accept the client's connection |
| request it should respond by closing the connection with a suitable reply |
| code. |
| </doc> |
| </rule> |
| </field> |
| </method> |
| |
| <method name = "open-ok" synchronous = "1" index = "41" label = "signal that connection is ready"> |
| <doc> |
| This method signals to the client that the connection is ready for use. |
| </doc> |
| <chassis name = "client" implement = "MUST" /> |
| <field name = "known-hosts" domain = "known-hosts" /> |
| </method> |
| |
| <method name = "redirect" synchronous = "1" index = "42" label = "redirects client to other server"> |
| <doc> |
| This method redirects the client to another server, based on the requested virtual |
| host and/or capabilities. |
| </doc> |
| <rule name = "usage"> |
| <doc> |
| When getting the Connection.Redirect method, the client SHOULD reconnect to |
| the host specified, and if that host is not present, to any of the hosts |
| specified in the known-hosts list. |
| </doc> |
| </rule> |
| <chassis name = "client" implement = "MUST" /> |
| <field name = "host" domain = "shortstr" label = "server to connect to"> |
| <doc> |
| Specifies the server to connect to. This is an IP address or a DNS name, |
| optionally followed by a colon and a port number. If no port number is |
| specified, the client should use the default port number for the protocol. |
| </doc> |
| <assert check = "notnull" /> |
| </field> |
| <field name = "known-hosts" domain = "known-hosts" /> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "close" synchronous = "1" index = "50" label = "request a connection close"> |
| <doc> |
| This method indicates that the sender wants to close the connection. This may be |
| due to internal conditions (e.g. a forced shut-down) or due to an error handling |
| a specific method, i.e. an exception. When a close is due to an exception, the |
| sender provides the class and method id of the method which caused the exception. |
| </doc> |
| <!-- TODO: the connection close mechanism needs to be reviewed from the ODF |
| documentation and better expressed as rules here. /PH 2006/07/20 |
| --> |
| <rule name = "stability"> |
| <doc> |
| After sending this method any received method except the Close-OK method MUST |
| be discarded. |
| </doc> |
| </rule> |
| |
| <chassis name = "client" implement = "MUST" /> |
| <chassis name = "server" implement = "MUST" /> |
| <response name = "close-ok" /> |
| |
| <field name = "reply-code" domain = "reply-code" /> |
| <field name = "reply-text" domain = "reply-text" /> |
| |
| <field name = "class-id" domain = "class-id" label = "failing method class"> |
| <doc> |
| When the close is provoked by a method exception, this is the class of the |
| method. |
| </doc> |
| </field> |
| |
| <field name = "method-id" domain = "method-id" label = "failing method ID"> |
| <doc> |
| When the close is provoked by a method exception, this is the ID of the method. |
| </doc> |
| </field> |
| </method> |
| |
| <method name = "close-ok" synchronous = "1" index = "51" label = "confirm a connection close"> |
| <doc> |
| This method confirms a Connection.Close method and tells the recipient that it is |
| safe to release resources for the connection and close the socket. |
| </doc> |
| <rule name = "reporting"> |
| <doc> |
| A peer that detects a socket closure without having received a Close-Ok |
| handshake method SHOULD log the error. |
| </doc> |
| </rule> |
| <chassis name = "client" implement = "MUST" /> |
| <chassis name = "server" implement = "MUST" /> |
| </method> |
| </class> |
| |
| <!-- == CHANNEL ========================================================== --> |
| |
| <class name = "channel" handler = "channel" index = "20" label = "work with channels"> |
| <doc> |
| The channel class provides methods for a client to establish a channel to a |
| server and for both peers to operate the channel thereafter. |
| </doc> |
| |
| <doc type = "grammar"> |
| channel = open-channel *use-channel close-channel |
| open-channel = C:OPEN S:OPEN-OK |
| use-channel = C:FLOW S:FLOW-OK |
| / S:FLOW C:FLOW-OK |
| / S:ALERT |
| / functional-class |
| close-channel = C:CLOSE S:CLOSE-OK |
| / S:CLOSE C:CLOSE-OK |
| </doc> |
| |
| <chassis name = "server" implement = "MUST" /> |
| <chassis name = "client" implement = "MUST" /> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "open" synchronous = "1" index = "10" label = "open a channel for use"> |
| <doc> |
| This method opens a channel to the server. |
| </doc> |
| <rule name = "state" on-failure = "channel-error"> |
| <doc> |
| The client MUST NOT use this method on an alread-opened channel. |
| </doc> |
| <doc type = "scenario"> |
| Client opens a channel and then reopens the same channel. |
| </doc> |
| </rule> |
| <chassis name = "server" implement = "MUST" /> |
| <response name = "open-ok" /> |
| <field name = "out of band" domain = "shortstr" label = "out-of-band settings"> |
| <doc> |
| Configures out-of-band transfers on this channel. The syntax and meaning of this |
| field will be formally defined at a later date. |
| </doc> |
| <assert check = "null" /> |
| </field> |
| </method> |
| |
| <method name = "open-ok" synchronous = "1" index = "11" label = "signal that the channel is ready"> |
| <doc> |
| This method signals to the client that the channel is ready for use. |
| </doc> |
| <chassis name = "client" implement = "MUST" /> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "flow" synchronous = "1" index = "20" label = "enable/disable flow from peer"> |
| <doc> |
| This method asks the peer to pause or restart the flow of content data. This is a |
| simple flow-control mechanism that a peer can use to avoid oveflowing its queues or |
| otherwise finding itself receiving more messages than it can process. Note that this |
| method is not intended for window control. The peer that receives a disable flow |
| method should finish sending the current content frame, if any, then pause. |
| </doc> |
| |
| <rule name = "initial-state"> |
| <doc> |
| When a new channel is opened, it is active (flow is active). Some applications |
| assume that channels are inactive until started. To emulate this behaviour a |
| client MAY open the channel, then pause it. |
| </doc> |
| </rule> |
| |
| <rule name = "bidirectional"> |
| <doc> |
| When sending content frames, a peer SHOULD monitor the channel for incoming |
| methods and respond to a Channel.Flow as rapidly as possible. |
| </doc> |
| </rule> |
| |
| <rule name = "throttling"> |
| <doc> |
| A peer MAY use the Channel.Flow method to throttle incoming content data for |
| internal reasons, for example, when exchanging data over a slower connection. |
| </doc> |
| </rule> |
| |
| <rule name = "expected-behaviour"> |
| <doc> |
| The peer that requests a Channel.Flow method MAY disconnect and/or ban a peer |
| that does not respect the request. This is to prevent badly-behaved clients |
| from overwhelming a broker. |
| </doc> |
| </rule> |
| |
| <chassis name = "server" implement = "MUST" /> |
| <chassis name = "client" implement = "MUST" /> |
| |
| <response name = "flow-ok" /> |
| |
| <field name = "active" domain = "bit" label = "start/stop content frames"> |
| <doc> |
| If 1, the peer starts sending content frames. If 0, the peer stops sending |
| content frames. |
| </doc> |
| </field> |
| </method> |
| |
| <method name = "flow-ok" index = "21" label = "confirm a flow method"> |
| <doc> |
| Confirms to the peer that a flow command was received and processed. |
| </doc> |
| <chassis name = "server" implement = "MUST" /> |
| <chassis name = "client" implement = "MUST" /> |
| <field name = "active" domain = "bit" label = "current flow setting"> |
| <doc> |
| Confirms the setting of the processed flow method: 1 means the peer will start |
| sending or continue to send content frames; 0 means it will not. |
| </doc> |
| </field> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| <!-- TODO 0.82 - remove this method entirely |
| /PH 2006/07/20 |
| --> |
| <method name = "alert" index = "30" label = "send a non-fatal warning message"> |
| <doc> |
| This method allows the server to send a non-fatal warning to the client. This is |
| used for methods that are normally asynchronous and thus do not have confirmations, |
| and for which the server may detect errors that need to be reported. Fatal errors |
| are handled as channel or connection exceptions; non-fatal errors are sent through |
| this method. |
| </doc> |
| <chassis name = "client" implement = "MUST" /> |
| <field name = "reply-code" domain = "reply-code" /> |
| <field name = "reply-text" domain = "reply-text" /> |
| <field name = "details" domain = "table" label = "detailed information for warning"> |
| <doc> |
| A set of fields that provide more information about the problem. The meaning of |
| these fields are defined on a per-reply-code basis (TO BE DEFINED). |
| </doc> |
| </field> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "close" synchronous = "1" index = "40" label = "request a channel close"> |
| <doc> |
| This method indicates that the sender wants to close the channel. This may be due to |
| internal conditions (e.g. a forced shut-down) or due to an error handling a specific |
| method, i.e. an exception. When a close is due to an exception, the sender provides |
| the class and method id of the method which caused the exception. |
| </doc> |
| |
| <!-- TODO: the channel close behaviour needs to be reviewed from the ODF |
| documentation and better expressed as rules here. /PH 2006/07/20 |
| --> |
| <rule name = "stability"> |
| <doc> |
| After sending this method any received method except the Close-OK method MUST |
| be discarded. |
| </doc> |
| </rule> |
| |
| <chassis name = "client" implement = "MUST" /> |
| <chassis name = "server" implement = "MUST" /> |
| <response name = "close-ok" /> |
| |
| <field name = "reply-code" domain = "reply-code" /> |
| <field name = "reply-text" domain = "reply-text" /> |
| |
| <field name = "class-id" domain = "class-id" label = "failing method class"> |
| <doc> |
| When the close is provoked by a method exception, this is the class of the |
| method. |
| </doc> |
| </field> |
| |
| <field name = "method-id" domain = "method-id" label = "failing method ID"> |
| <doc> |
| When the close is provoked by a method exception, this is the ID of the method. |
| </doc> |
| </field> |
| </method> |
| |
| <method name = "close-ok" synchronous = "1" index = "41" label = "confirm a channel close"> |
| <doc> |
| This method confirms a Channel.Close method and tells the recipient that it is safe |
| to release resources for the channel and close the socket. |
| </doc> |
| <rule name = "reporting"> |
| <doc> |
| A peer that detects a socket closure without having received a Channel.Close-Ok |
| handshake method SHOULD log the error. |
| </doc> |
| </rule> |
| <chassis name = "client" implement = "MUST" /> |
| <chassis name = "server" implement = "MUST" /> |
| </method> |
| </class> |
| |
| <!-- == ACCESS =========================================================== --> |
| |
| <!-- TODO 0.82 - this class must be implemented by two teams before we can |
| consider it matured. |
| --> |
| |
| <class name = "access" handler = "connection" index = "30" label = "work with access tickets"> |
| <doc> |
| The protocol control access to server resources using access tickets. A |
| client must explicitly request access tickets before doing work. An access |
| ticket grants a client the right to use a specific set of resources - |
| called a "realm" - in specific ways. |
| </doc> |
| |
| <doc type = "grammar"> |
| access = C:REQUEST S:REQUEST-OK |
| </doc> |
| |
| <chassis name = "server" implement = "MUST" /> |
| <chassis name = "client" implement = "MUST" /> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "request" synchronous = "1" index = "10" label = "request an access ticket"> |
| <doc> |
| This method requests an access ticket for an access realm. The server |
| responds by granting the access ticket. If the client does not have |
| access rights to the requested realm this causes a connection exception. |
| Access tickets are a per-channel resource. |
| </doc> |
| |
| <chassis name = "server" implement = "MUST" /> |
| <response name = "request-ok" /> |
| |
| <field name = "realm" domain = "shortstr" label = "name of requested realm"> |
| <doc> |
| Specifies the name of the realm to which the client is requesting access. |
| The realm is a configured server-side object that collects a set of |
| resources (exchanges, queues, etc.). If the channel has already requested |
| an access ticket onto this realm, the previous ticket is destroyed and a |
| new ticket is created with the requested access rights, if allowed. |
| </doc> |
| <rule name = "validity" on-failure = "access-refused"> |
| <doc> |
| The client MUST specify a realm that is known to the server. The server |
| makes an identical response for undefined realms as it does for realms |
| that are defined but inaccessible to this client. |
| </doc> |
| <doc type = "scenario"> |
| Client specifies an undefined realm. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "exclusive" domain = "bit" label = "request exclusive access"> |
| <doc> |
| Request exclusive access to the realm, meaning that this will be the only |
| channel that uses the realm's resources. |
| </doc> |
| <rule name = "validity" on-failure = "access-refused"> |
| <doc> |
| The client MAY NOT request exclusive access to a realm that has active |
| access tickets, unless the same channel already had the only access |
| ticket onto that realm. |
| </doc> |
| <doc type = "scenario"> |
| Client opens two channels and requests exclusive access to the same realm. |
| </doc> |
| </rule> |
| </field> |
| <field name = "passive" domain = "bit" label = "request passive access"> |
| <doc> |
| Request message passive access to the specified access realm. Passive |
| access lets a client get information about resources in the realm but |
| not to make any changes to them. |
| </doc> |
| </field> |
| <field name = "active" domain = "bit" label = "request active access"> |
| <doc> |
| Request message active access to the specified access realm. Active access lets |
| a client get create and delete resources in the realm. |
| </doc> |
| </field> |
| <field name = "write" domain = "bit" label = "request write access"> |
| <doc> |
| Request write access to the specified access realm. Write access lets a client |
| publish messages to all exchanges in the realm. |
| </doc> |
| </field> |
| <field name = "read" domain = "bit" label = "request read access"> |
| <doc> |
| Request read access to the specified access realm. Read access lets a client |
| consume messages from queues in the realm. |
| </doc> |
| </field> |
| </method> |
| |
| <method name = "request-ok" synchronous = "1" index = "11" label = "grant access to server resources"> |
| <doc> |
| This method provides the client with an access ticket. The access ticket is valid |
| within the current channel and for the lifespan of the channel. |
| </doc> |
| <rule name = "per-channel" on-failure = "not-allowed"> |
| <doc> |
| The client MUST NOT use access tickets except within the same channel as |
| originally granted. |
| </doc> |
| <doc type = "scenario"> |
| Client opens two channels, requests a ticket on one channel, and then |
| tries to use that ticket in a seconc channel. |
| </doc> |
| </rule> |
| <chassis name = "client" implement = "MUST" /> |
| <field name = "ticket" domain = "access-ticket" /> |
| </method> |
| </class> |
| |
| <!-- == EXCHANGE ========================================================= --> |
| |
| <class name = "exchange" handler = "channel" index = "40" label = "work with exchanges"> |
| <doc> |
| Exchanges match and distribute messages across queues. Exchanges can be configured in |
| the server or created at runtime. |
| </doc> |
| |
| <doc type = "grammar"> |
| exchange = C:DECLARE S:DECLARE-OK |
| / C:DELETE S:DELETE-OK |
| </doc> |
| |
| <chassis name = "server" implement = "MUST" /> |
| <chassis name = "client" implement = "MUST" /> |
| |
| <rule name = "required-types"> |
| <doc> |
| The server MUST implement these standard exchange types: fanout, direct. |
| </doc> |
| <doc type = "scenario"> |
| Client attempts to declare an exchange with each of these standard types. |
| </doc> |
| </rule> |
| <rule name = "recommended-types"> |
| <doc> |
| The server SHOULD implement these standard exchange types: topic, headers. |
| </doc> |
| <doc type = "scenario"> |
| Client attempts to declare an exchange with each of these standard types. |
| </doc> |
| </rule> |
| <rule name = "required-instances"> |
| <doc> |
| The server MUST, in each virtual host, pre-declare an exchange instance |
| for each standard exchange type that it implements, where the name of the |
| exchange instance is "amq." followed by the exchange type name. |
| </doc> |
| <doc type = "scenario"> |
| Client creates a temporary queue and attempts to bind to each required |
| exchange instance (amq.fanout, amq.direct, and amq.topic, amq.headers if |
| those types are defined). |
| </doc> |
| </rule> |
| <rule name = "default-exchange"> |
| <doc> |
| The server MUST predeclare a direct exchange to act as the default exchange |
| for content Publish methods and for default queue bindings. |
| </doc> |
| <doc type = "scenario"> |
| Client checks that the default exchange is active by specifying a queue |
| binding with no exchange name, and publishing a message with a suitable |
| routing key but without specifying the exchange name, then ensuring that |
| the message arrives in the queue correctly. |
| </doc> |
| </rule> |
| <rule name = "default-access"> |
| <doc> |
| The server MUST NOT allow clients to access the default exchange except |
| by specifying an empty exchange name in the Queue.Bind and content Publish |
| methods. |
| </doc> |
| </rule> |
| <rule name = "extensions"> |
| <doc> |
| The server MAY implement other exchange types as wanted. |
| </doc> |
| </rule> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "declare" synchronous = "1" index = "10" label = "declare exchange, create if needed"> |
| <doc> |
| This method creates an exchange if it does not already exist, and if the exchange |
| exists, verifies that it is of the correct and expected class. |
| </doc> |
| <rule name = "minimum"> |
| <doc> |
| The server SHOULD support a minimum of 16 exchanges per virtual host and |
| ideally, impose no limit except as defined by available resources. |
| </doc> |
| <doc type = "scenario"> |
| The client creates as many exchanges as it can until the server reports |
| an error; the number of exchanges successfuly created must be at least |
| sixteen. |
| </doc> |
| </rule> |
| |
| <chassis name = "server" implement = "MUST" /> |
| <response name = "declare-ok" /> |
| |
| <field name = "ticket" domain = "access-ticket"> |
| <doc> |
| When a client defines a new exchange, this belongs to the access realm of the |
| ticket used. All further work done with that exchange must be done with an |
| access ticket for the same realm. |
| </doc> |
| <rule name = "validity" on-failure = "access-refused"> |
| <doc> |
| The client MUST provide a valid access ticket giving "active" access to |
| the realm in which the exchange exists or will be created, or "passive" |
| access if the if-exists flag is set. |
| </doc> |
| <doc type = "scenario"> |
| Client creates access ticket with wrong access rights and attempts to use |
| in this method. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "exchange" domain = "exchange-name"> |
| <rule name = "reserved" on-failure = "access-refused"> |
| <doc> |
| Exchange names starting with "amq." are reserved for predeclared and |
| standardised exchanges. The client MUST NOT attempt to create an exchange |
| starting with "amq.". |
| </doc> |
| <doc type = "scenario"> |
| TODO. |
| </doc> |
| </rule> |
| <assert check = "regexp" value = "^[a-zA-Z0-9-_.:]+$" /> |
| </field> |
| |
| <field name = "type" domain = "shortstr" label = "exchange type"> |
| <doc> |
| Each exchange belongs to one of a set of exchange types implemented by the |
| server. The exchange types define the functionality of the exchange - i.e. how |
| messages are routed through it. It is not valid or meaningful to attempt to |
| change the type of an existing exchange. |
| </doc> |
| <rule name = "typed" on-failure = "not-allowed"> |
| <doc> |
| Exchanges cannot be redeclared with different types. The client MUST not |
| attempt to redeclare an existing exchange with a different type than used |
| in the original Exchange.Declare method. |
| </doc> |
| <doc type = "scenario"> |
| TODO. |
| </doc> |
| </rule> |
| <rule name = "support" on-failure = "command-invalid"> |
| <doc> |
| The client MUST NOT attempt to create an exchange with a type that the |
| server does not support. |
| </doc> |
| <doc type = "scenario"> |
| TODO. |
| </doc> |
| </rule> |
| <assert check = "regexp" value = "^[a-zA-Z0-9-_.:]+$" /> |
| </field> |
| |
| <field name = "passive" domain = "bit" label = "do not create exchange"> |
| <doc> |
| If set, the server will not create the exchange. The client can use this to |
| check whether an exchange exists without modifying the server state. |
| </doc> |
| <rule name = "not-found"> |
| <doc> |
| If set, and the exchange does not already exist, the server MUST raise a |
| channel exception with reply code 404 (not found). |
| </doc> |
| <doc type = "scenario"> |
| TODO. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "durable" domain = "bit" label = "request a durable exchange"> |
| <doc> |
| If set when creating a new exchange, the exchange will be marked as durable. |
| Durable exchanges remain active when a server restarts. Non-durable exchanges |
| (transient exchanges) are purged if/when a server restarts. |
| </doc> |
| <rule name = "support"> |
| <doc> |
| The server MUST support both durable and transient exchanges. |
| </doc> |
| <doc type = "scenario"> |
| TODO. |
| </doc> |
| </rule> |
| <rule name = "sticky"> |
| <doc> |
| The server MUST ignore the durable field if the exchange already exists. |
| </doc> |
| <doc type = "scenario"> |
| TODO. |
| </doc> |
| </rule> |
| </field> |
| |
| <!-- TODO 0.82 - clarify how this works; there is no way to cancel a binding |
| except by deleting a queue. |
| --> |
| <field name = "auto-delete" domain = "bit" label = "auto-delete when unused"> |
| <doc> |
| If set, the exchange is deleted when all queues have finished using it. |
| </doc> |
| <rule name = "sticky"> |
| <doc> |
| The server MUST ignore the auto-delete field if the exchange already |
| exists. |
| </doc> |
| <doc type = "scenario"> |
| TODO. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "internal" domain = "bit" label = "create internal exchange"> |
| <doc> |
| If set, the exchange may not be used directly by publishers, but only when bound |
| to other exchanges. Internal exchanges are used to construct wiring that is not |
| visible to applications. |
| </doc> |
| </field> |
| |
| <field name = "arguments" domain = "table" label = "arguments for declaration"> |
| <doc> |
| A set of arguments for the declaration. The syntax and semantics of these |
| arguments depends on the server implementation. This field is ignored if passive |
| is 1. |
| </doc> |
| </field> |
| </method> |
| |
| <method name = "declare-ok" synchronous = "1" index = "11" label = "confirm exchange declaration"> |
| <doc> |
| This method confirms a Declare method and confirms the name of the exchange, |
| essential for automatically-named exchanges. |
| </doc> |
| <chassis name = "client" implement = "MUST" /> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "delete" synchronous = "1" index = "20" label = "delete an exchange"> |
| <doc> |
| This method deletes an exchange. When an exchange is deleted all queue bindings on |
| the exchange are cancelled. |
| </doc> |
| |
| <chassis name = "server" implement = "MUST" /> |
| <response name = "delete-ok" /> |
| |
| <field name = "ticket" domain = "access-ticket"> |
| <rule name = "validity" on-failure = "access-refused"> |
| <doc> |
| The client MUST provide a valid access ticket giving "active" access |
| rights to the exchange's access realm. |
| </doc> |
| <doc type = "scenario"> |
| Client creates access ticket with wrong access rights and attempts to use |
| in this method. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "exchange" domain = "exchange-name"> |
| <rule name = "exists" on-failure = "not-found"> |
| <doc> |
| The client MUST NOT attempt to delete an exchange that does not exist. |
| </doc> |
| </rule> |
| <assert check = "notnull" /> |
| </field> |
| |
| <!-- TODO 0.82 - discuss whether this option is useful or not. I don't have |
| any real use case for it. /PH 2006-07-23. |
| --> |
| <field name = "if-unused" domain = "bit" label = "delete only if unused"> |
| <doc> |
| If set, the server will only delete the exchange if it has no queue bindings. If |
| the exchange has queue bindings the server does not delete it but raises a |
| channel exception instead. |
| </doc> |
| </field> |
| </method> |
| |
| <method name = "delete-ok" synchronous = "1" index = "21" |
| label = "confirm deletion of an exchange"> |
| <doc>This method confirms the deletion of an exchange.</doc> |
| <chassis name = "client" implement = "MUST" /> |
| </method> |
| </class> |
| |
| <!-- == QUEUE ============================================================ --> |
| |
| <class name = "queue" handler = "channel" index = "50" label = "work with queues"> |
| <doc> |
| Queues store and forward messages. Queues can be configured in the server or created at |
| runtime. Queues must be attached to at least one exchange in order to receive messages |
| from publishers. |
| </doc> |
| |
| <doc type = "grammar"> |
| queue = C:DECLARE S:DECLARE-OK |
| / C:BIND S:BIND-OK |
| / C:PURGE S:PURGE-OK |
| / C:DELETE S:DELETE-OK |
| </doc> |
| |
| <chassis name = "server" implement = "MUST" /> |
| <chassis name = "client" implement = "MUST" /> |
| |
| <rule name = "any-content"> |
| <doc> |
| A server MUST allow any content class to be sent to any queue, in any mix, and |
| queue and deliver these content classes independently. Note that all methods |
| that fetch content off queues are specific to a given content class. |
| </doc> |
| <doc type = "scenario"> |
| Client creates an exchange of each standard type and several queues that |
| it binds to each exchange. It must then sucessfully send each of the standard |
| content types to each of the available queues. |
| </doc> |
| </rule> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "declare" synchronous = "1" index = "10" label = "declare queue, create if needed"> |
| <doc> |
| This method creates or checks a queue. When creating a new queue the client can |
| specify various properties that control the durability of the queue and its |
| contents, and the level of sharing for the queue. |
| </doc> |
| |
| <rule name = "default-binding"> |
| <doc> |
| The server MUST create a default binding for a newly-created queue to the |
| default exchange, which is an exchange of type 'direct'. |
| </doc> |
| <doc type = "scenario"> |
| Client creates a new queue, and then without explicitly binding it to an |
| exchange, attempts to send a message through the default exchange binding, |
| i.e. publish a message to the empty exchange, with the queue name as routing |
| key. |
| </doc> |
| </rule> |
| |
| <!-- Rule test name: was "amq_queue_35" --> |
| <rule name = "minimum-queues"> |
| <doc> |
| The server SHOULD support a minimum of 256 queues per virtual host and ideally, |
| impose no limit except as defined by available resources. |
| </doc> |
| <doc type = "scenario"> |
| Client attempts to create as many queues as it can until the server reports |
| an error. The resulting count must at least be 256. |
| </doc> |
| </rule> |
| |
| <chassis name = "server" implement = "MUST" /> |
| <response name = "declare-ok" /> |
| |
| <field name = "ticket" domain = "access-ticket"> |
| <doc> |
| When a client defines a new queue, this belongs to the access realm of the |
| ticket used. All further work done with that queue must be done with an access |
| ticket for the same realm. |
| </doc> |
| <rule name = "validity" on-failure = "access-refused"> |
| <doc> |
| The client MUST provide a valid access ticket giving "active" access to |
| the realm in which the queue exists or will be created. |
| </doc> |
| <doc type = "scenario"> |
| Client creates access ticket with wrong access rights and attempts to use |
| in this method. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "queue" domain = "queue-name"> |
| <rule name = "default-name"> |
| <doc> |
| The queue name MAY be empty, in which case the server MUST create a new |
| queue with a unique generated name and return this to the client in the |
| Declare-Ok method. |
| </doc> |
| <doc type = "scenario"> |
| Client attempts to create several queues with an empty name. The client then |
| verifies that the server-assigned names are unique and different. |
| </doc> |
| </rule> |
| <rule name = "reserved-prefix" on-failure = "not-allowed"> |
| <doc> |
| Queue names starting with "amq." are reserved for predeclared and |
| standardised server queues. A client MAY NOT attempt to declare a queue with a |
| name that starts with "amq." and the passive option set to zero. |
| </doc> |
| <doc type = "scenario"> |
| A client attempts to create a queue with a name starting with "amq." and with |
| the passive option set to zero. |
| </doc> |
| </rule> |
| <assert check = "regexp" value = "^[a-zA-Z0-9-_.:]*$" /> |
| </field> |
| |
| <field name = "passive" domain = "bit" label = "do not create queue"> |
| <doc> |
| If set, the server will not create the queue. This field allows the client |
| to assert the presence of a queue without modifying the server state. |
| </doc> |
| <rule name = "passive" on-failure = "not-found"> |
| <doc> |
| The client MAY ask the server to assert that a queue exists without |
| creating the queue if not. If the queue does not exist, the server |
| treats this as a failure. |
| </doc> |
| <doc type = "scenario"> |
| Client declares an existing queue with the passive option and expects |
| the server to respond with a declare-ok. Client then attempts to declare |
| a non-existent queue with the passive option, and the server must close |
| the channel with the correct reply-code. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "durable" domain = "bit" label = "request a durable queue"> |
| <doc> |
| If set when creating a new queue, the queue will be marked as durable. Durable |
| queues remain active when a server restarts. Non-durable queues (transient |
| queues) are purged if/when a server restarts. Note that durable queues do not |
| necessarily hold persistent messages, although it does not make sense to send |
| persistent messages to a transient queue. |
| </doc> |
| <!-- Rule test name: was "amq_queue_03" --> |
| <rule name = "persistence"> |
| <doc>The server MUST recreate the durable queue after a restart.</doc> |
| |
| <!-- TODO: use 'client does something' rather than 'a client does something'. --> |
| <doc type = "scenario"> |
| A client creates a durable queue. The server is then restarted. The client |
| then attempts to send a message to the queue. The message should be successfully |
| delivered. |
| </doc> |
| </rule> |
| <!-- Rule test name: was "amq_queue_36" --> |
| <rule name = "types"> |
| <doc>The server MUST support both durable and transient queues.</doc> |
| <doc type = "scenario"> |
| A client creates two named queues, one durable and one transient. |
| </doc> |
| </rule> |
| <!-- Rule test name: was "amq_queue_37" --> |
| <rule name = "pre-existence"> |
| <doc>The server MUST ignore the durable field if the queue already exists.</doc> |
| <doc type = "scenario"> |
| A client creates two named queues, one durable and one transient. The client |
| then attempts to declare the two queues using the same names again, but reversing |
| the value of the durable flag in each case. Verify that the queues still exist |
| with the original durable flag values. |
| <!-- TODO: but how? --> |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "exclusive" domain = "bit" label = "request an exclusive queue"> |
| <doc> |
| Exclusive queues may only be consumed from by the current connection. Setting |
| the 'exclusive' flag always implies 'auto-delete'. |
| </doc> |
| |
| <!-- Rule test name: was "amq_queue_38" --> |
| <rule name = "types"> |
| <doc> |
| The server MUST support both exclusive (private) and non-exclusive (shared) |
| queues. |
| </doc> |
| <doc type = "scenario"> |
| A client creates two named queues, one exclusive and one non-exclusive. |
| </doc> |
| </rule> |
| |
| <!-- Rule test name: was "amq_queue_04" --> |
| <rule name = "02" on-failure = "channel-error"> |
| <doc> |
| The client MAY NOT attempt to declare any existing and exclusive queue |
| on multiple connections. |
| </doc> |
| <doc type = "scenario"> |
| A client declares an exclusive named queue. A second client on a different |
| connection attempts to declare a queue of the same name. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "auto-delete" domain = "bit" label = "auto-delete queue when unused"> |
| <doc> |
| If set, the queue is deleted when all consumers have finished using it. Last |
| consumer can be cancelled either explicitly or because its channel is closed. If |
| there was no consumer ever on the queue, it won't be deleted. |
| </doc> |
| |
| <!-- Rule test name: was "amq_queue_31" --> |
| <rule name = "pre-existence"> |
| <doc> |
| The server MUST ignore the auto-delete field if the queue already exists. |
| </doc> |
| <doc type = "scenario"> |
| A client creates two named queues, one as auto-delete and one explicit-delete. |
| The client then attempts to declare the two queues using the same names again, |
| but reversing the value of the auto-delete field in each case. Verify that the |
| queues still exist with the original auto-delete flag values. |
| <!-- TODO: but how? --> |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "arguments" domain = "table" label = "arguments for declaration"> |
| <doc> |
| A set of arguments for the declaration. The syntax and semantics of these |
| arguments depends on the server implementation. This field is ignored if passive |
| is 1. |
| </doc> |
| </field> |
| </method> |
| |
| <method name = "declare-ok" synchronous = "1" index = "11" label = "confirms a queue definition"> |
| <doc> |
| This method confirms a Declare method and confirms the name of the queue, essential |
| for automatically-named queues. |
| </doc> |
| |
| <chassis name = "client" implement = "MUST" /> |
| |
| <field name = "queue" domain = "queue-name"> |
| <doc> |
| Reports the name of the queue. If the server generated a queue name, this field |
| contains that name. |
| </doc> |
| <assert check = "notnull" /> |
| </field> |
| |
| <field name = "message-count" domain = "long" label = "number of messages in queue"> |
| <doc> |
| Reports the number of messages in the queue, which will be zero for |
| newly-created queues. |
| </doc> |
| </field> |
| |
| <field name = "consumer-count" domain = "long" label = "number of consumers"> |
| <doc> |
| Reports the number of active consumers for the queue. Note that consumers can |
| suspend activity (Channel.Flow) in which case they do not appear in this count. |
| </doc> |
| </field> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "bind" synchronous = "1" index = "20" label = "bind queue to an exchange"> |
| <doc> |
| This method binds a queue to an exchange. Until a queue is bound it will not receive |
| any messages. In a classic messaging model, store-and-forward queues are bound to a |
| dest exchange and subscription queues are bound to a dest_wild exchange. |
| </doc> |
| |
| <!-- Rule test name: was "amq_queue_25" --> |
| <rule name = "duplicates"> |
| <doc> |
| A server MUST allow ignore duplicate bindings - that is, two or more bind |
| methods for a specific queue, with identical arguments - without treating these |
| as an error. |
| </doc> |
| <doc type = "scenario"> |
| A client binds a named queue to an exchange. The client then repeats the bind |
| (with identical arguments). |
| </doc> |
| </rule> |
| |
| <!-- Rule test name: was "amq_queue_39" --> |
| <rule name = "failure" on-failure = "??????"> |
| <!-- |
| TODO: Find correct code. The on-failure code returned should depend on why the bind |
| failed. Assuming that failures owing to bad parameters are covered in the rules relating |
| to those parameters, the only remaining reason for a failure would be the lack of |
| server resorces or some internal error - such as too many queues open. Would these |
| cases qualify as "resource error" 506 or "internal error" 541? |
| --> |
| <doc>If a bind fails, the server MUST raise a connection exception.</doc> |
| <doc type = "scenario"> |
| TODO |
| </doc> |
| </rule> |
| |
| <!-- Rule test name: was "amq_queue_12" --> |
| <rule name = "transient-exchange" on-failure = "not-allowed"> |
| <doc> |
| The server MUST NOT allow a durable queue to bind to a transient exchange. |
| </doc> |
| <doc type = "scenario"> |
| A client creates a transient exchange. The client then declares a named durable |
| queue and then attempts to bind the transient exchange to the durable queue. |
| </doc> |
| </rule> |
| |
| <!-- Rule test name: was "amq_queue_13" --> |
| <rule name = "durable-exchange"> |
| <doc> |
| Bindings for durable queues are automatically durable and the server SHOULD |
| restore such bindings after a server restart. |
| </doc> |
| <doc type = "scenario"> |
| A server creates a named durable queue and binds it to a durable exchange. The |
| server is restarted. The client then attempts to use the queue/exchange combination. |
| </doc> |
| </rule> |
| |
| <!-- Rule test name: was "amq_queue_17" --> |
| <rule name = "internal-exchange"> |
| <doc> |
| If the client attempts to bind to an exchange that was declared as internal, the server |
| MUST raise a connection exception with reply code 530 (not allowed). |
| </doc> |
| <doc type = "scenario"> |
| A client attempts to bind a named queue to an internal exchange. |
| </doc> |
| </rule> |
| |
| <!-- Rule test name: was "amq_queue_40" --> |
| <rule name = "binding-count"> |
| <doc> |
| The server SHOULD support at least 4 bindings per queue, and ideally, impose no |
| limit except as defined by available resources. |
| </doc> |
| <doc type = "scenario"> |
| A client creates a named queue and attempts to bind it to 4 different non-internal |
| exchanges. |
| </doc> |
| </rule> |
| |
| <chassis name = "server" implement = "MUST" /> |
| |
| <response name = "bind-ok" /> |
| |
| <field name = "ticket" domain = "access-ticket"> |
| <doc> |
| The client provides a valid access ticket giving "active" access rights to the |
| queue's access realm. |
| </doc> |
| </field> |
| |
| <field name = "queue" domain = "queue-name"> |
| <doc> |
| Specifies the name of the queue to bind. If the queue name is empty, refers to |
| the current queue for the channel, which is the last declared queue. |
| </doc> |
| |
| <rule name = "empty-queue" on-failure = "not-allowed"> |
| <doc> |
| A client MUST NOT be allowed to bind a non-existent and unnamed queue (i.e. |
| empty queue name) to an exchange. |
| </doc> |
| <doc type = "scenario"> |
| A client attempts to bind with an unnamed (empty) queue name to an exchange. |
| </doc> |
| </rule> |
| |
| <!-- Rule test name: was "amq_queue_26" --> |
| <rule name = "queue-existence" on-failure = "not-found"> |
| <doc> |
| A client MUST NOT be allowed to bind a non-existent queue (i.e. not previously |
| declared) to an exchange. |
| </doc> |
| <doc type = "scenario"> |
| A client attempts to bind an undeclared queue name to an exchange. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "exchange" domain = "exchange-name" label = "name of the exchange to bind to"> |
| <!-- Rule test name: was "amq_queue_14" --> |
| <rule name = "exchange-existence" on-failure = "not-found"> |
| <doc> |
| A client MUST NOT be allowed to bind a queue to a non-existent exchange. |
| </doc> |
| <doc type = "scenario"> |
| A client attempts to bind an named queue to a undeclared exchange. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "routing-key" domain = "shortstr" label = "message routing key"> |
| <doc> |
| Specifies the routing key for the binding. The routing key is used for routing |
| messages depending on the exchange configuration. Not all exchanges use a |
| routing key - refer to the specific exchange documentation. If the queue name |
| is empty, the server uses the last queue declared on the channel. If the |
| routing key is also empty, the server uses this queue name for the routing |
| key as well. If the queue name is provided but the routing key is empty, the |
| server does the binding with that empty routing key. The meaning of empty |
| routing keys depends on the exchange implementation. |
| </doc> |
| </field> |
| |
| <field name = "arguments" domain = "table" label = "arguments for binding"> |
| <doc> |
| A set of arguments for the binding. The syntax and semantics of these arguments |
| depends on the exchange class. |
| </doc> |
| </field> |
| </method> |
| |
| <method name = "bind-ok" synchronous = "1" index = "21" label = "confirm bind successful"> |
| <doc>This method confirms that the bind was successful.</doc> |
| |
| <chassis name = "client" implement = "MUST" /> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "purge" synchronous = "1" index = "30" label = "purge a queue"> |
| <doc> |
| This method removes all messages from a queue. It does not cancel consumers. Purged |
| messages are deleted without any formal "undo" mechanism. |
| </doc> |
| |
| <!-- Rule test name: was "amq_queue_15" --> |
| <rule name = "01"> |
| <doc>A call to purge MUST result in an empty queue.</doc> |
| </rule> |
| |
| <!-- Rule test name: was "amq_queue_41" --> |
| <rule name = "02"> |
| <doc> |
| On transacted channels the server MUST not purge messages that have already been |
| sent to a client but not yet acknowledged. |
| </doc> |
| </rule> |
| |
| <!-- TODO: Rule split? --> |
| |
| <!-- Rule test name: was "amq_queue_42" --> |
| <rule name = "03"> |
| <doc> |
| The server MAY implement a purge queue or log that allows system administrators |
| to recover accidentally-purged messages. The server SHOULD NOT keep purged |
| messages in the same storage spaces as the live messages since the volumes of |
| purged messages may get very large. |
| </doc> |
| </rule> |
| |
| <chassis name = "server" implement = "MUST" /> |
| |
| <response name = "purge-ok" /> |
| |
| <field name = "ticket" domain = "access-ticket"> |
| <doc>The access ticket must be for the access realm that holds the queue.</doc> |
| |
| <rule name = "01"> |
| <doc> |
| The client MUST provide a valid access ticket giving "read" access rights to |
| the queue's access realm. Note that purging a queue is equivalent to reading |
| all messages and discarding them. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "queue" domain = "queue-name"> |
| <doc> |
| Specifies the name of the queue to purge. If the queue name is empty, refers to |
| the current queue for the channel, which is the last declared queue. |
| </doc> |
| |
| <rule name = "01"> |
| <doc> |
| If the client did not previously declare a queue, and the queue name in this |
| method is empty, the server MUST raise a connection exception with reply |
| code 530 (not allowed). |
| </doc> |
| </rule> |
| |
| <!-- TODO Rule split? --> |
| |
| <!-- Rule test name: was "amq_queue_16" --> |
| <rule name = "02"> |
| <doc> |
| The queue MUST exist. Attempting to purge a non-existing queue MUST cause a |
| channel exception. |
| </doc> |
| </rule> |
| </field> |
| </method> |
| |
| <method name = "purge-ok" synchronous = "1" index = "31" label = "confirms a queue purge"> |
| <doc>This method confirms the purge of a queue.</doc> |
| |
| <chassis name = "client" implement = "MUST" /> |
| |
| <field name = "message-count" domain = "long" label = "number of messages purged"> |
| <doc>Reports the number of messages purged.</doc> |
| </field> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "delete" synchronous = "1" index = "40" label = "delete a queue"> |
| <doc> |
| This method deletes a queue. When a queue is deleted any pending messages are sent |
| to a dead-letter queue if this is defined in the server configuration, and all |
| consumers on the queue are cancelled. |
| </doc> |
| |
| <!-- TODO: Rule split? --> |
| |
| <!-- Rule test name: was "amq_queue_43" --> |
| <rule name = "01"> |
| <doc> |
| The server SHOULD use a dead-letter queue to hold messages that were pending on |
| a deleted queue, and MAY provide facilities for a system administrator to move |
| these messages back to an active queue. |
| </doc> |
| </rule> |
| |
| <chassis name = "server" implement = "MUST" /> |
| |
| <response name = "delete-ok" /> |
| |
| <field name = "ticket" domain = "access-ticket"> |
| <doc> |
| The client provides a valid access ticket giving "active" access rights to the |
| queue's access realm. |
| </doc> |
| </field> |
| |
| <field name = "queue" domain = "queue-name"> |
| <doc> |
| Specifies the name of the queue to delete. If the queue name is empty, refers to |
| the current queue for the channel, which is the last declared queue. |
| </doc> |
| |
| <rule name = "01"> |
| <doc> |
| If the client did not previously declare a queue, and the queue name in this |
| method is empty, the server MUST raise a connection exception with reply |
| code 530 (not allowed). |
| </doc> |
| </rule> |
| |
| <!-- Rule test name: was "amq_queue_21" --> |
| <rule name = "02"> |
| <doc> |
| The queue must exist. If the client attempts to delete a non-existing queue |
| the server MUST raise a channel exception with reply code 404 (not found). |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "if-unused" domain = "bit" label = "delete only if unused"> |
| <doc> |
| If set, the server will only delete the queue if it has no consumers. If the |
| queue has consumers the server does does not delete it but raises a channel |
| exception instead. |
| </doc> |
| |
| <!-- Rule test name: was "amq_queue_29" and "amq_queue_30" --> |
| <rule name = "01"> |
| <doc>The server MUST respect the if-unused flag when deleting a queue.</doc> |
| </rule> |
| </field> |
| |
| <field name = "if-empty" domain = "bit" label = "delete only if empty"> |
| <doc> |
| If set, the server will only delete the queue if it has no messages. |
| </doc> |
| <rule name = "01"> |
| <doc> |
| If the queue is not empty the server MUST raise a channel exception with |
| reply code 406 (precondition failed). |
| </doc> |
| </rule> |
| </field> |
| </method> |
| |
| <method name = "delete-ok" synchronous = "1" index = "41" label = "confirm deletion of a queue"> |
| <doc>This method confirms the deletion of a queue.</doc> |
| |
| <chassis name = "client" implement = "MUST" /> |
| |
| <field name = "message-count" domain = "long" label = "number of messages purged"> |
| <doc>Reports the number of messages purged.</doc> |
| </field> |
| </method> |
| </class> |
| |
| <!-- == BASIC ============================================================ --> |
| |
| <class name = "basic" handler = "channel" index = "60" label = "work with basic content"> |
| <doc> |
| The Basic class provides methods that support an industry-standard messaging model. |
| </doc> |
| |
| <doc type = "grammar"> |
| basic = C:QOS S:QOS-OK |
| / C:CONSUME S:CONSUME-OK |
| / C:CANCEL S:CANCEL-OK |
| / C:PUBLISH content |
| / S:RETURN content |
| / S:DELIVER content |
| / C:GET ( S:GET-OK content / S:GET-EMPTY ) |
| / C:ACK |
| / C:REJECT |
| </doc> |
| |
| <chassis name = "server" implement = "MUST" /> |
| <chassis name = "client" implement = "MAY" /> |
| |
| <!-- Rule test name: was "amq_basic_08" --> |
| <rule name = "01"> |
| <doc> |
| The server SHOULD respect the persistent property of basic messages and |
| SHOULD make a best-effort to hold persistent basic messages on a reliable |
| storage mechanism. |
| </doc> |
| <doc type = "scenario"> |
| Send a persistent message to queue, stop server, restart server and then |
| verify whether message is still present. Assumes that queues are durable. |
| Persistence without durable queues makes no sense. |
| </doc> |
| </rule> |
| |
| <!-- Rule test name: was "amq_basic_09" --> |
| <rule name = "02"> |
| <doc> |
| The server MUST NOT discard a persistent basic message in case of a queue |
| overflow. |
| </doc> |
| <doc type = "scenario"> |
| Create a queue overflow situation with persistent messages and verify that |
| messages do not get lost (presumably the server will write them to disk). |
| </doc> |
| </rule> |
| |
| <rule name = "03"> |
| <doc> |
| The server MAY use the Channel.Flow method to slow or stop a basic message |
| publisher when necessary. |
| </doc> |
| <doc type = "scenario"> |
| Create a queue overflow situation with non-persistent messages and verify |
| whether the server responds with Channel.Flow or not. Repeat with persistent |
| messages. |
| </doc> |
| </rule> |
| |
| <!-- Rule test name: was "amq_basic_10" --> |
| <rule name = "04"> |
| <doc> |
| The server MAY overflow non-persistent basic messages to persistent |
| storage. |
| </doc> |
| <!-- Test scenario: untestable --> |
| </rule> |
| |
| <rule name = "05"> |
| <doc> |
| The server MAY discard or dead-letter non-persistent basic messages on a |
| priority basis if the queue size exceeds some configured limit. |
| </doc> |
| <!-- Test scenario: untestable --> |
| </rule> |
| |
| <!-- Rule test name: was "amq_basic_11" --> |
| <rule name = "06"> |
| <doc> |
| The server MUST implement at least 2 priority levels for basic messages, |
| where priorities 0-4 and 5-9 are treated as two distinct levels. |
| </doc> |
| <doc type = "scenario"> |
| Send a number of priority 0 messages to a queue. Send one priority 9 |
| message. Consume messages from the queue and verify that the first message |
| received was priority 9. |
| </doc> |
| </rule> |
| |
| <rule name = "07"> |
| <doc> |
| The server MAY implement up to 10 priority levels. |
| </doc> |
| <doc type = "scenario"> |
| Send a number of messages with mixed priorities to a queue, so that all |
| priority values from 0 to 9 are exercised. A good scenario would be ten |
| messages in low-to-high priority. Consume from queue and verify how many |
| priority levels emerge. |
| </doc> |
| </rule> |
| |
| <!-- Rule test name: was "amq_basic_12" --> |
| <rule name = "08"> |
| <doc> |
| The server MUST deliver messages of the same priority in order irrespective of |
| their individual persistence. |
| </doc> |
| <doc type = "scenario"> |
| Send a set of messages with the same priority but different persistence |
| settings to a queue. Consume and verify that messages arrive in same order |
| as originally published. |
| </doc> |
| </rule> |
| |
| <!-- Rule test name: was "amq_basic_13" --> |
| <rule name = "09"> |
| <doc> |
| The server MUST support automatic acknowledgements on Basic content, i.e. |
| consumers with the no-ack field set to FALSE. |
| </doc> |
| <doc type = "scenario"> |
| Create a queue and a consumer using automatic acknowledgements. Publish |
| a set of messages to the queue. Consume the messages and verify that all |
| messages are received. |
| </doc> |
| </rule> |
| |
| <rule name = "10"> |
| <doc> |
| The server MUST support explicit acknowledgements on Basic content, i.e. |
| consumers with the no-ack field set to TRUE. |
| </doc> |
| <doc type = "scenario"> |
| Create a queue and a consumer using explicit acknowledgements. Publish a |
| set of messages to the queue. Consume the messages but acknowledge only |
| half of them. Disconnect and reconnect, and consume from the queue. |
| Verify that the remaining messages are received. |
| </doc> |
| </rule> |
| |
| <!-- These are the properties for a Basic content --> |
| |
| <field name = "content-type" domain = "shortstr" label = "MIME content type" /> |
| <field name = "content-encoding" domain = "shortstr" label = "MIME content encoding" /> |
| <field name = "headers" domain = "table" label = "message header field table" /> |
| <field name = "delivery-mode" domain = "octet" label = "non-persistent (1) or persistent (2)" /> |
| <field name = "priority" domain = "short" label = "message priority, 0 to 9" /> |
| <field name = "correlation-id" domain = "shortstr" label = "application correlation identifier" /> |
| <field name = "reply-to" domain = "shortstr" label = "destination to reply to" /> |
| <field name = "expiration" domain = "shortstr" label = "message expiration specification" /> |
| <field name = "timestamp" domain = "timestamp" label = "message timestamp" /> |
| <field name = "message-id" domain = "shortstr" label = "application message identifier" /> |
| <field name = "type" domain = "shortstr" label = "message type name" /> |
| <field name = "user-id" domain = "shortstr" label = "creating user id" /> |
| <field name = "app-id" domain = "shortstr" label = "creating application id" /> |
| <!-- This field is deprecated pending review --> |
| <field name = "cluster-id" domain = "shortstr" label = "intra-cluster routing identifier" /> |
| |
| <!-- Type diversity test --> |
| <field name = "property-bit" domain = "bit" label = "Extra property for testing only" /> |
| <field name = "property-octet" domain = "octet" label = "Extra property for testing only" /> |
| <field name = "property-short" domain = "short" label = "Extra property for testing only" /> |
| <field name = "property-long" domain = "long" label = "Extra property for testing only" /> |
| <field name = "property-longlong" domain = "longlong" label = "Extra property for testing only" /> |
| <field name = "property-shortstr" domain = "shortstr" label = "Extra property for testing only" /> |
| <field name = "property-longstr" domain = "longstr" label = "Extra property for testing only" /> |
| <field name = "property-timestamp" domain = "timestamp" label = "Extra property for testing only" /> |
| <field name = "property-table" domain = "table" label = "Extra property for testing only" /> |
| <field name = "property-access-ticket" domain = "access-ticket" label = "Extra property for testing only" /> |
| <field name = "property-class-id" domain = "class-id" label = "Extra property for testing only" /> |
| <field name = "property-consumer-tag" domain = "consumer-tag" label = "Extra property for testing only" /> |
| <field name = "property-delivery-tag" domain = "delivery-tag" label = "Extra property for testing only" /> |
| <field name = "property-exchange-name" domain = "exchange-name" label = "Extra property for testing only" /> |
| <field name = "property-known-hosts" domain = "known-hosts" label = "Extra property for testing only" /> |
| <field name = "property-method-id" domain = "method-id" label = "Extra property for testing only" /> |
| <field name = "property-no-ack" domain = "no-ack" label = "Extra property for testing only" /> |
| <field name = "property-no-local" domain = "no-local" label = "Extra property for testing only" /> |
| <field name = "property-path" domain = "path" label = "Extra property for testing only" /> |
| <field name = "property-peer-properties" domain = "peer-properties" label = "Extra property for testing only" /> |
| <field name = "property-queue-name" domain = "queue-name" label = "Extra property for testing only" /> |
| <field name = "property-redelivered" domain = "redelivered" label = "Extra property for testing only" /> |
| <field name = "property-reply-code" domain = "reply-code" label = "Extra property for testing only" /> |
| <field name = "property-reply-text" domain = "reply-text" label = "Extra property for testing only" /> |
| |
| <!-- Bit field test --> |
| <field name = "property-long-A" domain = "long" label = "Extra property for testing only" /> |
| <field name = "property-bit-B" domain = "bit" label = "Extra property for testing only" /> |
| <field name = "property-bit-C" domain = "bit" label = "Extra property for testing only" /> |
| <field name = "property-bit-D" domain = "bit" label = "Extra property for testing only" /> |
| <field name = "property-bit-E" domain = "bit" label = "Extra property for testing only" /> |
| <field name = "property-bit-F" domain = "bit" label = "Extra property for testing only" /> |
| <field name = "property-shortstr-G" domain = "shortstr" label = "Extra property for testing only" /> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "qos" synchronous = "1" index = "10" label = "specify quality of service"> |
| <doc> |
| This method requests a specific quality of service. The QoS can be specified for the |
| current channel or for all channels on the connection. The particular properties and |
| semantics of a qos method always depend on the content class semantics. Though the |
| qos method could in principle apply to both peers, it is currently meaningful only |
| for the server. |
| </doc> |
| |
| <chassis name = "server" implement = "MUST" /> |
| <response name = "qos-ok" /> |
| |
| <field name = "prefetch-size" domain = "long" label = "prefetch window in octets"> |
| <doc> |
| The client can request that messages be sent in advance so that when the client |
| finishes processing a message, the following message is already held locally, |
| rather than needing to be sent down the channel. Prefetching gives a performance |
| improvement. This field specifies the prefetch window size in octets. The server |
| will send a message in advance if it is equal to or smaller in size than the |
| available prefetch size (and also falls into other prefetch limits). May be set |
| to zero, meaning "no specific limit", although other prefetch limits may still |
| apply. The prefetch-size is ignored if the no-ack option is set. |
| </doc> |
| <!-- Rule test name: was "amq_basic_17" --> |
| <rule name = "01"> |
| <doc> |
| The server MUST ignore this setting when the client is not processing any |
| messages - i.e. the prefetch size does not limit the transfer of single |
| messages to a client, only the sending in advance of more messages while |
| the client still has one or more unacknowledged messages. |
| </doc> |
| <doc type = "scenario"> |
| Define a QoS prefetch-size limit and send a single message that exceeds |
| that limit. Verify that the message arrives correctly. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "prefetch-count" domain = "short" label = "prefetch window in messages"> |
| <doc> |
| Specifies a prefetch window in terms of whole messages. This field may be used |
| in combination with the prefetch-size field; a message will only be sent in |
| advance if both prefetch windows (and those at the channel and connection level) |
| allow it. The prefetch-count is ignored if the no-ack option is set. |
| </doc> |
| <!-- Rule test name: was "amq_basic_18" --> |
| <rule name = "01"> |
| <doc> |
| The server may send less data in advance than allowed by the client's |
| specified prefetch windows but it MUST NOT send more. |
| </doc> |
| <doc type = "scenario"> |
| Define a QoS prefetch-size limit and a prefetch-count limit greater than |
| one. Send multiple messages that exceed the prefetch size. Verify that |
| no more than one message arrives at once. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "global" domain = "bit" label = "apply to entire connection"> |
| <doc> |
| By default the QoS settings apply to the current channel only. If this field is |
| set, they are applied to the entire connection. |
| </doc> |
| </field> |
| </method> |
| |
| <method name = "qos-ok" synchronous = "1" index = "11" label = "confirm the requested qos"> |
| <doc> |
| This method tells the client that the requested QoS levels could be handled by the |
| server. The requested QoS applies to all active consumers until a new QoS is |
| defined. |
| </doc> |
| <chassis name = "client" implement = "MUST" /> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "consume" synchronous = "1" index = "20" label = "start a queue consumer"> |
| <doc> |
| This method asks the server to start a "consumer", which is a transient request for |
| messages from a specific queue. Consumers last as long as the channel they were |
| created on, or until the client cancels them. |
| </doc> |
| |
| <!-- Rule test name: was "amq_basic_01" --> |
| <rule name = "01"> |
| <doc> |
| The server SHOULD support at least 16 consumers per queue, and ideally, impose |
| no limit except as defined by available resources. |
| </doc> |
| <doc type = "scenario"> |
| Create a queue and create consumers on that queue until the server closes the |
| connection. Verify that the number of consumers created was at least sixteen |
| and report the total number. |
| </doc> |
| </rule> |
| |
| <chassis name = "server" implement = "MUST" /> |
| <response name = "consume-ok" /> |
| |
| <field name = "ticket" domain = "access-ticket"> |
| <rule name = "01" on-failure = "access-refused"> |
| <doc> |
| The client MUST provide a valid access ticket giving "read" access rights to |
| the realm for the queue. |
| </doc> |
| <doc type = "scenario"> |
| Attempt to create a consumer with an invalid (non-zero) access ticket. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "queue" domain = "queue-name"> |
| <doc> |
| Specifies the name of the queue to consume from. If the queue name is null, |
| refers to the current queue for the channel, which is the last declared queue. |
| </doc> |
| <rule name = "01" on-failure = "not-allowed"> |
| <doc> |
| If the queue name is empty the client MUST have previously declared a |
| queue using this channel. |
| </doc> |
| <doc type = "scenario"> |
| Attempt to create a consumer with an empty queue name and no previously |
| declared queue on the channel. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "consumer-tag" domain = "consumer-tag"> |
| <doc> |
| Specifies the identifier for the consumer. The consumer tag is local to a |
| connection, so two clients can use the same consumer tags. If this field is |
| empty the server will generate a unique tag. |
| </doc> |
| <rule name = "01" on-failure = "not-allowed"> |
| <doc> |
| The client MUST NOT specify a tag that refers to an existing consumer. |
| </doc> |
| <doc type = "scenario"> |
| Attempt to create two consumers with the same non-empty tag. |
| </doc> |
| </rule> |
| <rule name = "02" on-failure = "not-allowed"> |
| <doc> |
| The consumer tag is valid only within the channel from which the |
| consumer was created. I.e. a client MUST NOT create a consumer in one |
| channel and then use it in another. |
| </doc> |
| <doc type = "scenario"> |
| Attempt to create a consumer in one channel, then use in another channel, |
| in which consumers have also been created (to test that the server uses |
| unique consumer tags). |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "no-local" domain = "no-local" /> |
| |
| <field name = "nowait" domain = "bit" label = "do not send a reply method"> |
| <doc> |
| If set, the server will not respond to the method. The client should not wait |
| for a reply method. If the server could not complete the method it will raise |
| a channel or connection exception. |
| </doc> |
| </field> |
| |
| <field name = "bit-test-1" domain = "bit" /> |
| <field name = "bit-test-2" domain = "bit" /> |
| <field name = "bit-test-3" domain = "bit" /> |
| <field name = "bit-test-4" domain = "bit" /> |
| <field name = "bit-test-5" domain = "bit" /> |
| <field name = "bit-test-6" domain = "bit" /> |
| <field name = "bit-test-7" domain = "bit" /> |
| <field name = "bit-test-8" domain = "bit" /> |
| <field name = "bit-test-9" domain = "bit" /> |
| |
| <field name = "no-ack" domain = "short" /> |
| |
| <field name = "exclusive" domain = "bit" label = "request exclusive access"> |
| <doc> |
| Request exclusive consumer access, meaning only this consumer can access the |
| queue. |
| </doc> |
| <!-- Rule test name: was "amq_basic_02" --> |
| <rule name = "01" on-failure = "access-refused"> |
| <doc> |
| The client MAY NOT gain exclusive access to a queue that already has |
| active consumers. |
| </doc> |
| <doc type = "scenario"> |
| Open two connections to a server, and in one connection create a shared |
| (non-exclusive) queue and then consume from the queue. In the second |
| connection attempt to consume from the same queue using the exclusive |
| option. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "priority" domain = "short" label = "consume priority"/> |
| </method> |
| |
| <method name = "consume-ok" synchronous = "1" index = "21" label = "confirm a new consumer"> |
| <doc> |
| The server provides the client with a consumer tag, which is used by the client |
| for methods called on the consumer at a later stage. |
| </doc> |
| <chassis name = "client" implement = "MUST" /> |
| <field name = "consumer-tag" domain = "consumer-tag"> |
| <doc> |
| Holds the consumer tag specified by the client or provided by the server. |
| </doc> |
| </field> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "cancel" synchronous = "1" index = "30" label = "end a queue consumer"> |
| <doc> |
| This method cancels a consumer. This does not affect already delivered |
| messages, but it does mean the server will not send any more messages for |
| that consumer. The client may receive an abitrary number of messages in |
| between sending the cancel method and receiving the cancel-ok reply. |
| </doc> |
| |
| <rule name = "01"> |
| <doc> |
| If the queue does not exist the server MUST ignore the cancel method, so |
| long as the consumer tag is valid for that channel. |
| </doc> |
| <doc type = "scenario"> |
| TODO. |
| </doc> |
| </rule> |
| |
| <chassis name = "server" implement = "MUST" /> |
| <response name = "cancel-ok" /> |
| |
| <field name = "consumer-tag" domain = "consumer-tag" /> |
| </method> |
| |
| <method name = "cancel-ok" synchronous = "1" index = "31" label = "confirm a cancelled consumer"> |
| <doc> |
| This method confirms that the cancellation was completed. |
| </doc> |
| <chassis name = "client" implement = "MUST" /> |
| <field name = "consumer-tag" domain = "consumer-tag" /> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "publish" content = "1" index = "40" label = "publish a message"> |
| <doc> |
| This method publishes a message to a specific exchange. The message will be routed |
| to queues as defined by the exchange configuration and distributed to any active |
| consumers when the transaction, if any, is committed. |
| </doc> |
| |
| <chassis name = "server" implement = "MUST" /> |
| |
| <field name = "ticket" domain = "access-ticket"> |
| <rule name = "01"> |
| <doc> |
| The client MUST provide a valid access ticket giving "write" access rights |
| to the access realm for the exchange. |
| </doc> |
| <doc type = "scenario"> |
| TODO. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "exchange" domain = "exchange-name"> |
| <doc> |
| Specifies the name of the exchange to publish to. The exchange name can be |
| empty, meaning the default exchange. If the exchange name is specified, and that |
| exchange does not exist, the server will raise a channel exception. |
| </doc> |
| |
| <!-- Rule test name: was "amq_basic_06" --> |
| <rule name = "01"> |
| <doc> |
| The server MUST accept a blank exchange name to mean the default exchange. |
| </doc> |
| <doc type = "scenario"> |
| TODO. |
| </doc> |
| </rule> |
| |
| <!-- Rule test name: was "amq_basic_14" --> |
| <rule name = "02"> |
| <doc> |
| If the exchange was declared as an internal exchange, the server MUST raise |
| a channel exception with a reply code 403 (access refused). |
| </doc> |
| <doc type = "scenario"> |
| TODO. |
| </doc> |
| </rule> |
| |
| <!-- Rule test name: was "amq_basic_15" --> |
| <rule name = "03"> |
| <doc> |
| The exchange MAY refuse basic content in which case it MUST raise a channel |
| exception with reply code 540 (not implemented). |
| </doc> |
| <doc type = "scenario"> |
| TODO. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "routing-key" domain = "shortstr" label = "Message routing key"> |
| <doc> |
| Specifies the routing key for the message. The routing key is used for routing |
| messages depending on the exchange configuration. |
| </doc> |
| </field> |
| |
| <field name = "mandatory" domain = "bit" label = "indicate mandatory routing"> |
| <doc> |
| This flag tells the server how to react if the message cannot be routed to a |
| queue. If this flag is set, the server will return an unroutable message with a |
| Return method. If this flag is zero, the server silently drops the message. |
| </doc> |
| <!-- Rule test name: was "amq_basic_07" --> |
| <rule name = "01"> |
| <doc> |
| The server SHOULD implement the mandatory flag. |
| </doc> |
| <doc type = "scenario"> |
| TODO. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "immediate" domain = "bit" label = "request immediate delivery"> |
| <doc> |
| This flag tells the server how to react if the message cannot be routed to a |
| queue consumer immediately. If this flag is set, the server will return an |
| undeliverable message with a Return method. If this flag is zero, the server |
| will queue the message, but with no guarantee that it will ever be consumed. |
| </doc> |
| <!-- Rule test name: was "amq_basic_16" --> |
| <rule name = "01"> |
| <doc> |
| The server SHOULD implement the immediate flag. |
| </doc> |
| <doc type = "scenario"> |
| TODO. |
| </doc> |
| </rule> |
| </field> |
| </method> |
| |
| <method name = "return" content = "1" index = "50" label = "return a failed message"> |
| <doc> |
| This method returns an undeliverable message that was published with the "immediate" |
| flag set, or an unroutable message published with the "mandatory" flag set. The |
| reply code and text provide information about the reason that the message was |
| undeliverable. |
| </doc> |
| |
| <chassis name = "client" implement = "MUST" /> |
| |
| <field name = "reply-code" domain = "reply-code" /> |
| |
| <field name = "reply-text" domain = "reply-text" /> |
| |
| <field name = "exchange" domain = "exchange-name"> |
| <doc> |
| Specifies the name of the exchange that the message was originally published to. |
| </doc> |
| </field> |
| |
| <field name = "routing-key" domain = "shortstr" label = "Message routing key"> |
| <doc> |
| Specifies the routing key name specified when the message was published. |
| </doc> |
| </field> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "deliver" content = "1" index = "60" |
| label = "notify the client of a consumer message"> |
| <doc> |
| This method delivers a message to the client, via a consumer. In the asynchronous |
| message delivery model, the client starts a consumer using the Consume method, then |
| the server responds with Deliver methods as and when messages arrive for that |
| consumer. |
| </doc> |
| |
| <!-- Rule test name: was "amq_basic_19" --> |
| <rule name = "01"> |
| <!-- TODO: Rule split? --> |
| <doc> |
| The server SHOULD track the number of times a message has been delivered to |
| clients and when a message is redelivered a certain number of times - e.g. 5 |
| times - without being acknowledged, the server SHOULD consider the message to be |
| unprocessable (possibly causing client applications to abort), and move the |
| message to a dead letter queue. |
| </doc> |
| <doc type = "scenario"> |
| TODO. |
| </doc> |
| </rule> |
| |
| <chassis name = "client" implement = "MUST" /> |
| |
| <field name = "consumer-tag" domain = "consumer-tag" /> |
| |
| <field name = "delivery-tag" domain = "delivery-tag" /> |
| |
| <field name = "redelivered" domain = "redelivered" /> |
| |
| <field name = "exchange" domain = "exchange-name"> |
| <doc> |
| Specifies the name of the exchange that the message was originally published to. |
| </doc> |
| </field> |
| |
| <field name = "routing-key" domain = "shortstr" label = "Message routing key"> |
| <doc>Specifies the routing key name specified when the message was published.</doc> |
| </field> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "get" synchronous = "1" index = "70" label = "direct access to a queue"> |
| <doc> |
| This method provides a direct access to the messages in a queue using a synchronous |
| dialogue that is designed for specific types of application where synchronous |
| functionality is more important than performance. |
| </doc> |
| |
| <response name = "get-ok" /> |
| <response name = "get-empty" /> |
| <chassis name = "server" implement = "MUST" /> |
| |
| <field name = "ticket" domain = "access-ticket"> |
| <rule name = "01"> |
| <doc> |
| The client MUST provide a valid access ticket giving "read" access rights to |
| the realm for the queue. |
| </doc> |
| <doc type = "scenario"> |
| TODO. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "queue" domain = "queue-name"> |
| <doc> |
| Specifies the name of the queue to consume from. If the queue name is null, |
| refers to the current queue for the channel, which is the last declared queue. |
| </doc> |
| <rule name = "01"> |
| <doc> |
| If the client did not previously declare a queue, and the queue name in this |
| method is empty, the server MUST raise a connection exception with reply |
| code 530 (not allowed). |
| </doc> |
| <doc type = "scenario"> |
| TODO. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "no-ack" domain = "no-ack" /> |
| </method> |
| |
| <method name = "get-ok" synchronous = "1" content = "1" index = "71" |
| label = "provide client with a message"> |
| <doc> |
| This method delivers a message to the client following a get method. A message |
| delivered by 'get-ok' must be acknowledged unless the no-ack option was set in the |
| get method. |
| </doc> |
| |
| <chassis name = "client" implement = "MAY" /> |
| |
| <field name = "delivery-tag" domain = "delivery-tag" /> |
| |
| <field name = "redelivered" domain = "redelivered" /> |
| |
| <field name = "exchange" domain = "exchange-name"> |
| <doc> |
| Specifies the name of the exchange that the message was originally published to. |
| If empty, the message was published to the default exchange. |
| </doc> |
| </field> |
| |
| <field name = "routing-key" domain = "shortstr" label = "Message routing key"> |
| <doc>Specifies the routing key name specified when the message was published.</doc> |
| </field> |
| |
| <field name = "message-count" domain = "long" label = "number of messages pending"> |
| <doc> |
| This field reports the number of messages pending on the queue, excluding the |
| message being delivered. Note that this figure is indicative, not reliable, and |
| can change arbitrarily as messages are added to the queue and removed by other |
| clients. |
| </doc> |
| </field> |
| </method> |
| |
| <method name = "get-empty" synchronous = "1" index = "72" |
| label = "indicate no messages available"> |
| <doc> |
| This method tells the client that the queue has no messages available for the |
| client. |
| </doc> |
| |
| <chassis name = "client" implement = "MAY" /> |
| |
| <!-- This field is deprecated pending review --> |
| <field name = "cluster-id" domain = "shortstr" label = "Cluster id"> |
| <doc> |
| For use by cluster applications, should not be used by client applications. |
| </doc> |
| </field> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "ack" index = "80" label = "acknowledge one or more messages"> |
| <doc> |
| This method acknowledges one or more messages delivered via the Deliver or Get-Ok |
| methods. The client can ask to confirm a single message or a set of messages up to |
| and including a specific message. |
| </doc> |
| |
| <chassis name = "server" implement = "MUST" /> |
| |
| <field name = "delivery-tag" domain = "delivery-tag" /> |
| |
| <field name = "multiple" domain = "bit" label = "acknowledge multiple messages"> |
| <doc> |
| If set to 1, the delivery tag is treated as "up to and including", so that the |
| client can acknowledge multiple messages with a single method. If set to zero, |
| the delivery tag refers to a single message. If the multiple field is 1, and the |
| delivery tag is zero, tells the server to acknowledge all outstanding mesages. |
| </doc> |
| |
| <!-- Rule test name: was "amq_basic_20" --> |
| <rule name = "01"> |
| <doc> |
| The server MUST validate that a non-zero delivery-tag refers to an delivered |
| message, and raise a channel exception if this is not the case. |
| </doc> |
| <doc type = "scenario"> |
| TODO. |
| </doc> |
| </rule> |
| </field> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "reject" index = "90" label = "reject an incoming message"> |
| <doc> |
| This method allows a client to reject a message. It can be used to interrupt and |
| cancel large incoming messages, or return untreatable messages to their original |
| queue. |
| </doc> |
| |
| <!-- Rule test name: was "amq_basic_21" --> |
| <rule name = "01"> |
| <doc> |
| The server SHOULD be capable of accepting and process the Reject method while |
| sending message content with a Deliver or Get-Ok method. I.e. the server should |
| read and process incoming methods while sending output frames. To cancel a |
| partially-send content, the server sends a content body frame of size 1 (i.e. |
| with no data except the frame-end octet). |
| </doc> |
| </rule> |
| |
| <!-- Rule test name: was "amq_basic_22" --> |
| <rule name = "02"> |
| <doc> |
| The server SHOULD interpret this method as meaning that the client is unable to |
| process the message at this time. |
| </doc> |
| <doc type = "scenario"> |
| TODO. |
| </doc> |
| </rule> |
| |
| <rule name = "03"> |
| <!-- TODO: Rule split? --> |
| <doc> |
| A client MUST NOT use this method as a means of selecting messages to process. A |
| rejected message MAY be discarded or dead-lettered, not necessarily passed to |
| another client. |
| </doc> |
| <doc type = "scenario"> |
| TODO. |
| </doc> |
| </rule> |
| |
| <chassis name = "server" implement = "MUST" /> |
| |
| <field name = "delivery-tag" domain = "delivery-tag" /> |
| |
| <field name = "requeue" domain = "bit" label = "requeue the message"> |
| <doc> |
| If this field is zero, the message will be discarded. If this bit is 1, the |
| server will attempt to requeue the message. |
| </doc> |
| |
| <!-- Rule test name: was "amq_basic_23" --> |
| <rule name = "01"> |
| <!-- TODO: Rule split? --> |
| <doc> |
| The server MUST NOT deliver the message to the same client within the |
| context of the current channel. The recommended strategy is to attempt to |
| deliver the message to an alternative consumer, and if that is not possible, |
| to move the message to a dead-letter queue. The server MAY use more |
| sophisticated tracking to hold the message on the queue and redeliver it to |
| the same client at a later stage. |
| </doc> |
| <doc type = "scenario"> |
| TODO. |
| </doc> |
| </rule> |
| </field> |
| </method> |
| |
| <method name = "recover" index = "100" label = "redeliver unacknowledged messages"> |
| <doc> |
| This method asks the broker to redeliver all unacknowledged messages on a specified |
| channel. Zero or more messages may be redelivered. This method is only allowed on |
| non-transacted channels. |
| </doc> |
| |
| <rule name = "01"> |
| <doc> |
| The server MUST set the redelivered flag on all messages that are resent. |
| </doc> |
| <doc type = "scenario"> |
| TODO. |
| </doc> |
| </rule> |
| |
| <rule name = "02"> |
| <doc> |
| The server MUST raise a channel exception if this is called on a transacted |
| channel. |
| </doc> |
| <doc type = "scenario"> |
| TODO. |
| </doc> |
| </rule> |
| |
| <chassis name = "server" implement = "MUST" /> |
| |
| <field name = "requeue" domain = "bit" label = "requeue the message"> |
| <doc> |
| If this field is zero, the message will be redelivered to the original |
| recipient. If this bit is 1, the server will attempt to requeue the message, |
| potentially then delivering it to an alternative subscriber. |
| </doc> |
| </field> |
| </method> |
| </class> |
| |
| <!-- == FILE ============================================================= --> |
| |
| <class name = "file" handler = "channel" index = "70" label = "work with file content"> |
| <doc> |
| The file class provides methods that support reliable file transfer. File |
| messages have a specific set of properties that are required for interoperability |
| with file transfer applications. File messages and acknowledgements are subject to |
| channel transactions. Note that the file class does not provide message browsing |
| methods; these are not compatible with the staging model. Applications that need |
| browsable file transfer should use Basic content and the Basic class. |
| </doc> |
| |
| <doc type = "grammar"> |
| file = C:QOS S:QOS-OK |
| / C:CONSUME S:CONSUME-OK |
| / C:CANCEL S:CANCEL-OK |
| / C:OPEN S:OPEN-OK C:STAGE content |
| / S:OPEN C:OPEN-OK S:STAGE content |
| / C:PUBLISH |
| / S:DELIVER |
| / S:RETURN |
| / C:ACK |
| / C:REJECT |
| </doc> |
| |
| <chassis name = "server" implement = "MAY" /> |
| <chassis name = "client" implement = "MAY" /> |
| |
| <rule name = "01"> |
| <doc> |
| The server MUST make a best-effort to hold file messages on a reliable storage |
| mechanism. |
| </doc> |
| </rule> |
| |
| <!-- TODO Rule implement attr inverse? --> |
| |
| <!-- TODO: Rule split? --> |
| |
| <rule name = "02"> |
| <doc> |
| The server MUST NOT discard a file message in case of a queue overflow. The server |
| MUST use the Channel.Flow method to slow or stop a file message publisher when |
| necessary. |
| </doc> |
| </rule> |
| |
| <!-- TODO: Rule split? --> |
| |
| <rule name = "03"> |
| <doc> |
| The server MUST implement at least 2 priority levels for file messages, where |
| priorities 0-4 and 5-9 are treated as two distinct levels. The server MAY implement |
| up to 10 priority levels. |
| </doc> |
| </rule> |
| |
| <rule name = "04"> |
| <doc> |
| The server MUST support both automatic and explicit acknowledgements on file |
| content. |
| </doc> |
| </rule> |
| |
| <!-- These are the properties for a File content --> |
| |
| <field name = "content-type" domain = "shortstr" label = "MIME content type" /> |
| <field name = "content-encoding" domain = "shortstr" label = "MIME content encoding" /> |
| <field name = "headers" domain = "table" label = "message header field table" /> |
| <field name = "priority" domain = "octet" label = "message priority, 0 to 9" /> |
| <field name = "reply-to" domain = "shortstr" label = "destination to reply to" /> |
| <field name = "message-id" domain = "shortstr" label = "application message identifier" /> |
| <field name = "filename" domain = "shortstr" label = "message filename" /> |
| <field name = "timestamp" domain = "timestamp" label = "message timestamp" /> |
| <!-- This field is deprecated pending review --> |
| <field name = "cluster-id" domain = "shortstr" label = "intra-cluster routing identifier" /> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "qos" synchronous = "1" index = "10" label = "specify quality of service"> |
| <doc> |
| This method requests a specific quality of service. The QoS can be specified for the |
| current channel or for all channels on the connection. The particular properties and |
| semantics of a qos method always depend on the content class semantics. Though the |
| qos method could in principle apply to both peers, it is currently meaningful only |
| for the server. |
| </doc> |
| |
| <chassis name = "server" implement = "MUST" /> |
| |
| <response name = "qos-ok" /> |
| |
| <field name = "prefetch-size" domain = "long" label = "prefetch window in octets"> |
| <doc> |
| The client can request that messages be sent in advance so that when the client |
| finishes processing a message, the following message is already held locally, |
| rather than needing to be sent down the channel. Prefetching gives a performance |
| improvement. This field specifies the prefetch window size in octets. May be set |
| to zero, meaning "no specific limit". Note that other prefetch limits may still |
| apply. The prefetch-size is ignored if the no-ack option is set. |
| </doc> |
| </field> |
| |
| <field name = "prefetch-count" domain = "short" label = "prefetch window in messages"> |
| <doc> |
| Specifies a prefetch window in terms of whole messages. This is compatible with |
| some file API implementations. This field may be used in combination with the |
| prefetch-size field; a message will only be sent in advance if both prefetch |
| windows (and those at the channel and connection level) allow it. The |
| prefetch-count is ignored if the no-ack option is set. |
| </doc> |
| |
| <rule name = "01"> |
| <!-- TODO: Rule split? --> |
| <doc> |
| The server MAY send less data in advance than allowed by the client's |
| specified prefetch windows but it MUST NOT send more. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "global" domain = "bit" label = "apply to entire connection"> |
| <doc> |
| By default the QoS settings apply to the current channel only. If this field is |
| set, they are applied to the entire connection. |
| </doc> |
| </field> |
| </method> |
| |
| <method name = "qos-ok" synchronous = "1" index = "11" label = "confirm the requested qos"> |
| <doc> |
| This method tells the client that the requested QoS levels could be handled by the |
| server. The requested QoS applies to all active consumers until a new QoS is |
| defined. |
| </doc> |
| |
| <chassis name = "client" implement = "MUST" /> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "consume" synchronous = "1" index = "20" label = "start a queue consumer"> |
| <doc> |
| This method asks the server to start a "consumer", which is a transient request for |
| messages from a specific queue. Consumers last as long as the channel they were |
| created on, or until the client cancels them. |
| </doc> |
| |
| <rule name = "01"> |
| <doc> |
| The server SHOULD support at least 16 consumers per queue, unless the queue was |
| declared as private, and ideally, impose no limit except as defined by available |
| resources. |
| </doc> |
| </rule> |
| |
| <chassis name = "server" implement = "MUST" /> |
| |
| <response name = "consume-ok" /> |
| |
| <field name = "ticket" domain = "access-ticket"> |
| <rule name = "01"> |
| <doc> |
| The client MUST provide a valid access ticket giving "read" access rights to |
| the realm for the queue. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "queue" domain = "queue-name"> |
| <doc> |
| Specifies the name of the queue to consume from. If the queue name is null, |
| refers to the current queue for the channel, which is the last declared queue. |
| </doc> |
| |
| <rule name = "01"> |
| <doc> |
| If the client did not previously declare a queue, and the queue name in this |
| method is empty, the server MUST raise a connection exception with reply |
| code 530 (not allowed). |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "consumer-tag" domain = "consumer-tag"> |
| <doc> |
| Specifies the identifier for the consumer. The consumer tag is local to a |
| connection, so two clients can use the same consumer tags. If this field is |
| empty the server will generate a unique tag. |
| </doc> |
| |
| <rule name = "01"> |
| <!-- TODO: Rule split? --> |
| <doc> |
| The tag MUST NOT refer to an existing consumer. If the client attempts to |
| create two consumers with the same non-empty tag the server MUST raise a |
| connection exception with reply code 530 (not allowed). |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "no-local" domain = "no-local" /> |
| |
| <field name = "no-ack" domain = "no-ack" /> |
| |
| <field name = "exclusive" domain = "bit" label = "request exclusive access"> |
| <doc> |
| Request exclusive consumer access, meaning only this consumer can access the |
| queue. |
| </doc> |
| |
| <!-- Rule test name: was "amq_file_00" --> |
| <rule name = "01"> |
| <doc> |
| If the server cannot grant exclusive access to the queue when asked, - |
| because there are other consumers active - it MUST raise a channel exception |
| with return code 405 (resource locked). |
| </doc> |
| </rule> |
| </field> |
| </method> |
| |
| <method name = "consume-ok" synchronous = "1" index = "21" label = "confirm a new consumer"> |
| <doc> |
| This method provides the client with a consumer tag which it MUST use in methods |
| that work with the consumer. |
| </doc> |
| |
| <chassis name = "client" implement = "MUST" /> |
| |
| <field name = "consumer-tag" domain = "consumer-tag"> |
| <doc>Holds the consumer tag specified by the client or provided by the server.</doc> |
| </field> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "cancel" synchronous = "1" index = "30" label = "end a queue consumer"> |
| <doc> |
| This method cancels a consumer. This does not affect already delivered messages, but |
| it does mean the server will not send any more messages for that consumer. |
| </doc> |
| |
| <response name = "cancel-ok" /> |
| |
| <chassis name = "server" implement = "MUST" /> |
| |
| <field name = "consumer-tag" domain = "consumer-tag" /> |
| </method> |
| |
| <method name = "cancel-ok" synchronous = "1" index = "31" label = "confirm a cancelled consumer"> |
| <doc>This method confirms that the cancellation was completed.</doc> |
| |
| <chassis name = "client" implement = "MUST" /> |
| |
| <field name = "consumer-tag" domain = "consumer-tag" /> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "open" synchronous = "1" index = "40" label = "request to start staging"> |
| <doc> |
| This method requests permission to start staging a message. Staging means sending |
| the message into a temporary area at the recipient end and then delivering the |
| message by referring to this temporary area. Staging is how the protocol handles |
| partial file transfers - if a message is partially staged and the connection breaks, |
| the next time the sender starts to stage it, it can restart from where it left off. |
| </doc> |
| |
| <response name = "open-ok" /> |
| |
| <chassis name = "server" implement = "MUST" /> |
| <chassis name = "client" implement = "MUST" /> |
| |
| <field name = "identifier" domain = "shortstr" label = "staging identifier"> |
| <doc> |
| This is the staging identifier. This is an arbitrary string chosen by the |
| sender. For staging to work correctly the sender must use the same staging |
| identifier when staging the same message a second time after recovery from a |
| failure. A good choice for the staging identifier would be the SHA1 hash of the |
| message properties data (including the original filename, revised time, etc.). |
| </doc> |
| </field> |
| |
| <field name = "content-size" domain = "longlong" label = "message content size"> |
| <doc> |
| The size of the content in octets. The recipient may use this information to |
| allocate or check available space in advance, to avoid "disk full" errors during |
| staging of very large messages. |
| </doc> |
| |
| <rule name = "01"> |
| <doc> |
| The sender MUST accurately fill the content-size field. Zero-length content |
| is permitted. |
| </doc> |
| </rule> |
| </field> |
| </method> |
| |
| <method name = "open-ok" synchronous = "1" index = "41" label = "confirm staging ready"> |
| <doc> |
| This method confirms that the recipient is ready to accept staged data. If the |
| message was already partially-staged at a previous time the recipient will report |
| the number of octets already staged. |
| </doc> |
| |
| <response name = "stage" /> |
| |
| <chassis name = "server" implement = "MUST" /> |
| <chassis name = "client" implement = "MUST" /> |
| |
| <field name = "staged-size" domain = "longlong" label = "already staged amount"> |
| <doc> |
| The amount of previously-staged content in octets. For a new message this will |
| be zero. |
| </doc> |
| |
| <rule name = "01"> |
| <doc> |
| The sender MUST start sending data from this octet offset in the message, |
| counting from zero. |
| </doc> |
| </rule> |
| |
| <rule name = "02"> |
| <!-- TODO: Rule split? --> |
| <doc> |
| The recipient MAY decide how long to hold partially-staged content and MAY |
| implement staging by always discarding partially-staged content. However if |
| it uses the file content type it MUST support the staging methods. |
| </doc> |
| </rule> |
| </field> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "stage" content = "1" index = "50" label = "stage message content"> |
| <doc> |
| This method stages the message, sending the message content to the recipient from |
| the octet offset specified in the Open-Ok method. |
| </doc> |
| |
| <chassis name = "server" implement = "MUST" /> |
| <chassis name = "client" implement = "MUST" /> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "publish" index = "60" label = "publish a message"> |
| <doc> |
| This method publishes a staged file message to a specific exchange. The file message |
| will be routed to queues as defined by the exchange configuration and distributed to |
| any active consumers when the transaction, if any, is committed. |
| </doc> |
| |
| <chassis name = "server" implement = "MUST" /> |
| |
| <field name = "ticket" domain = "access-ticket"> |
| <rule name = "01"> |
| <doc> |
| The client MUST provide a valid access ticket giving "write" access rights |
| to the access realm for the exchange. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "exchange" domain = "exchange-name"> |
| <doc> |
| Specifies the name of the exchange to publish to. The exchange name can be |
| empty, meaning the default exchange. If the exchange name is specified, and that |
| exchange does not exist, the server will raise a channel exception. |
| </doc> |
| |
| <rule name = "01"> |
| <doc> |
| The server MUST accept a blank exchange name to mean the default exchange. |
| </doc> |
| </rule> |
| |
| <rule name = "02"> |
| <doc> |
| If the exchange was declared as an internal exchange, the server MUST |
| respond with a reply code 403 (access refused) and raise a channel |
| exception. |
| </doc> |
| </rule> |
| |
| <!-- TODO: Rule split? --> |
| |
| <rule name = "03"> |
| <doc> |
| The exchange MAY refuse file content in which case it MUST respond with a |
| reply code 540 (not implemented) and raise a channel exception. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "routing-key" domain = "shortstr" label = "Message routing key"> |
| <doc> |
| Specifies the routing key for the message. The routing key is used for routing |
| messages depending on the exchange configuration. |
| </doc> |
| </field> |
| |
| <field name = "mandatory" domain = "bit" label = "indicate mandatory routing"> |
| <doc> |
| This flag tells the server how to react if the message cannot be routed to a |
| queue. If this flag is set, the server will return an unroutable message with a |
| Return method. If this flag is zero, the server silently drops the message. |
| </doc> |
| |
| <!-- Rule test name: was "amq_file_00" --> |
| <rule name = "01"> |
| <doc>The server SHOULD implement the mandatory flag.</doc> |
| </rule> |
| </field> |
| |
| <field name = "immediate" domain = "bit" label = "request immediate delivery"> |
| <doc> |
| This flag tells the server how to react if the message cannot be routed to a |
| queue consumer immediately. If this flag is set, the server will return an |
| undeliverable message with a Return method. If this flag is zero, the server |
| will queue the message, but with no guarantee that it will ever be consumed. |
| </doc> |
| |
| <!-- Rule test name: was "amq_file_00" --> |
| <rule name = "01"> |
| <doc>The server SHOULD implement the immediate flag.</doc> |
| </rule> |
| </field> |
| |
| <field name = "identifier" domain = "shortstr" label = "staging identifier"> |
| <doc> |
| This is the staging identifier of the message to publish. The message must have |
| been staged. Note that a client can send the Publish method asynchronously |
| without waiting for staging to finish. |
| </doc> |
| </field> |
| </method> |
| |
| <method name = "return" content = "1" index = "70" label = "return a failed message"> |
| <doc> |
| This method returns an undeliverable message that was published with the "immediate" |
| flag set, or an unroutable message published with the "mandatory" flag set. The |
| reply code and text provide information about the reason that the message was |
| undeliverable. |
| </doc> |
| |
| <chassis name = "client" implement = "MUST" /> |
| |
| <field name = "reply-code" domain = "reply-code" /> |
| |
| <field name = "reply-text" domain = "reply-text" /> |
| |
| <field name = "exchange" domain = "exchange-name"> |
| <doc> |
| Specifies the name of the exchange that the message was originally published to. |
| </doc> |
| </field> |
| |
| <field name = "routing-key" domain = "shortstr" label = "Message routing key"> |
| <doc>Specifies the routing key name specified when the message was published.</doc> |
| </field> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "deliver" index = "80" label = "notify the client of a consumer message"> |
| <doc> |
| This method delivers a staged file message to the client, via a consumer. In the |
| asynchronous message delivery model, the client starts a consumer using the Consume |
| method, then the server responds with Deliver methods as and when messages arrive |
| for that consumer. |
| </doc> |
| |
| <rule name = "01"> |
| <!-- TODO: Rule split? --> |
| <doc> |
| The server SHOULD track the number of times a message has been delivered to |
| clients and when a message is redelivered a certain number of times - e.g. 5 |
| times - without being acknowledged, the server SHOULD consider the message to be |
| unprocessable (possibly causing client applications to abort), and move the |
| message to a dead letter queue. |
| </doc> |
| </rule> |
| |
| <chassis name = "client" implement = "MUST" /> |
| |
| <field name = "consumer-tag" domain = "consumer-tag" /> |
| |
| <field name = "delivery-tag" domain = "delivery-tag" /> |
| |
| <field name = "redelivered" domain = "redelivered" /> |
| |
| <field name = "exchange" domain = "exchange-name"> |
| <doc> |
| Specifies the name of the exchange that the message was originally published to. |
| </doc> |
| </field> |
| |
| <field name = "routing-key" domain = "shortstr" label = "Message routing key"> |
| <doc>Specifies the routing key name specified when the message was published.</doc> |
| </field> |
| |
| <field name = "identifier" domain = "shortstr" label = "staging identifier"> |
| <doc> |
| This is the staging identifier of the message to deliver. The message must have |
| been staged. Note that a server can send the Deliver method asynchronously |
| without waiting for staging to finish. |
| </doc> |
| </field> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "ack" index = "90" label = "acknowledge one or more messages"> |
| <doc> |
| This method acknowledges one or more messages delivered via the Deliver method. The |
| client can ask to confirm a single message or a set of messages up to and including |
| a specific message. |
| </doc> |
| |
| <chassis name = "server" implement = "MUST" /> |
| |
| <field name = "delivery-tag" domain = "delivery-tag" /> |
| |
| <field name = "multiple" domain = "bit" label = "acknowledge multiple messages"> |
| <doc> |
| If set to 1, the delivery tag is treated as "up to and including", so that the |
| client can acknowledge multiple messages with a single method. If set to zero, |
| the delivery tag refers to a single message. If the multiple field is 1, and the |
| delivery tag is zero, tells the server to acknowledge all outstanding mesages. |
| </doc> |
| |
| <rule name = "01"> |
| <doc> |
| The server MUST validate that a non-zero delivery-tag refers to an delivered |
| message, and raise a channel exception if this is not the case. |
| </doc> |
| </rule> |
| </field> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "reject" index = "100" label = "reject an incoming message"> |
| <doc> |
| This method allows a client to reject a message. It can be used to return |
| untreatable messages to their original queue. Note that file content is staged |
| before delivery, so the client will not use this method to interrupt delivery of a |
| large message. |
| </doc> |
| |
| <rule name = "01"> |
| <doc> |
| The server SHOULD interpret this method as meaning that the client is unable to |
| process the message at this time. |
| </doc> |
| </rule> |
| |
| <!-- TODO: Rule split? --> |
| |
| <rule name = "02"> |
| <doc> |
| A client MUST NOT use this method as a means of selecting messages to process. A |
| rejected message MAY be discarded or dead-lettered, not necessarily passed to |
| another client. |
| </doc> |
| </rule> |
| |
| <chassis name = "server" implement = "MUST" /> |
| |
| <field name = "delivery-tag" domain = "delivery-tag" /> |
| |
| <field name = "requeue" domain = "bit" label = "requeue the message"> |
| <doc> |
| If this field is zero, the message will be discarded. If this bit is 1, the |
| server will attempt to requeue the message. |
| </doc> |
| |
| <rule name = "01"> |
| <!-- TODO: Rule split? --> |
| <doc> |
| The server MUST NOT deliver the message to the same client within the |
| context of the current channel. The recommended strategy is to attempt to |
| deliver the message to an alternative consumer, and if that is not possible, |
| to move the message to a dead-letter queue. The server MAY use more |
| sophisticated tracking to hold the message on the queue and redeliver it to |
| the same client at a later stage. |
| </doc> |
| </rule> |
| </field> |
| </method> |
| </class> |
| |
| <!-- == STREAM =========================================================== --> |
| |
| <class name = "stream" handler = "channel" index = "80" label = "work with streaming content"> |
| <doc> |
| The stream class provides methods that support multimedia streaming. The stream class |
| uses the following semantics: one message is one packet of data; delivery is |
| unacknowleged and unreliable; the consumer can specify quality of service parameters |
| that the server can try to adhere to; lower-priority messages may be discarded in favour |
| of high priority messages. |
| </doc> |
| |
| <doc type = "grammar"> |
| stream = C:QOS S:QOS-OK |
| / C:CONSUME S:CONSUME-OK |
| / C:CANCEL S:CANCEL-OK |
| / C:PUBLISH content |
| / S:RETURN |
| / S:DELIVER content |
| </doc> |
| |
| <chassis name = "server" implement = "MAY" /> |
| <chassis name = "client" implement = "MAY" /> |
| |
| <rule name = "01"> |
| <doc> |
| The server SHOULD discard stream messages on a priority basis if the queue size |
| exceeds some configured limit. |
| </doc> |
| </rule> |
| |
| <rule name = "02"> |
| <!-- TODO: Rule split? --> |
| <doc> |
| The server MUST implement at least 2 priority levels for stream messages, where |
| priorities 0-4 and 5-9 are treated as two distinct levels. The server MAY implement |
| up to 10 priority levels. |
| </doc> |
| </rule> |
| |
| <rule name = "03"> |
| <doc> |
| The server MUST implement automatic acknowledgements on stream content. That is, as |
| soon as a message is delivered to a client via a Deliver method, the server must |
| remove it from the queue. |
| </doc> |
| </rule> |
| |
| <!-- These are the properties for a Stream content --> |
| |
| <field name = "content-type" domain = "shortstr" label = "MIME content type" /> |
| <field name = "content-encoding" domain = "shortstr" label = "MIME content encoding" /> |
| <field name = "headers" domain = "table" label = "message header field table" /> |
| <field name = "priority" domain = "octet" label = "message priority, 0 to 9" /> |
| <field name = "timestamp" domain = "timestamp" label = "message timestamp" /> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "qos" synchronous = "1" index = "10" label = "specify quality of service"> |
| <doc> |
| This method requests a specific quality of service. The QoS can be specified for the |
| current channel or for all channels on the connection. The particular properties and |
| semantics of a qos method always depend on the content class semantics. Though the |
| qos method could in principle apply to both peers, it is currently meaningful only |
| for the server. |
| </doc> |
| |
| <chassis name = "server" implement = "MUST" /> |
| |
| <response name = "qos-ok" /> |
| |
| <field name = "prefetch-size" domain = "long" label = "prefetch window in octets"> |
| <doc> |
| The client can request that messages be sent in advance so that when the client |
| finishes processing a message, the following message is already held locally, |
| rather than needing to be sent down the channel. Prefetching gives a performance |
| improvement. This field specifies the prefetch window size in octets. May be set |
| to zero, meaning "no specific limit". Note that other prefetch limits may still |
| apply. |
| </doc> |
| </field> |
| |
| <field name = "prefetch-count" domain = "short" label = "prefetch window in messages"> |
| <doc> |
| Specifies a prefetch window in terms of whole messages. This field may be used |
| in combination with the prefetch-size field; a message will only be sent in |
| advance if both prefetch windows (and those at the channel and connection level) |
| allow it. |
| </doc> |
| </field> |
| |
| <field name = "consume-rate" domain = "long" label = "transfer rate in octets/second"> |
| <doc> |
| Specifies a desired transfer rate in octets per second. This is usually |
| determined by the application that uses the streaming data. A value of zero |
| means "no limit", i.e. as rapidly as possible. |
| </doc> |
| |
| <rule name = "01"> |
| <!-- TODO: Rule split? --> |
| <doc> |
| The server MAY ignore the prefetch values and consume rates, depending on |
| the type of stream and the ability of the server to queue and/or reply it. |
| The server MAY drop low-priority messages in favour of high-priority |
| messages. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "global" domain = "bit" label = "apply to entire connection"> |
| <doc> |
| By default the QoS settings apply to the current channel only. If this field is |
| set, they are applied to the entire connection. |
| </doc> |
| </field> |
| </method> |
| |
| <method name = "qos-ok" synchronous = "1" index = "11" label = "confirm the requested qos"> |
| <doc> |
| This method tells the client that the requested QoS levels could be handled by the |
| server. The requested QoS applies to all active consumers until a new QoS is |
| defined. |
| </doc> |
| |
| <chassis name = "client" implement = "MUST" /> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "consume" synchronous = "1" index = "20" label = "start a queue consumer"> |
| <doc> |
| This method asks the server to start a "consumer", which is a transient request for |
| messages from a specific queue. Consumers last as long as the channel they were |
| created on, or until the client cancels them. |
| </doc> |
| |
| <rule name = "01"> |
| <doc> |
| The server SHOULD support at least 16 consumers per queue, unless the queue was |
| declared as private, and ideally, impose no limit except as defined by available |
| resources. |
| </doc> |
| </rule> |
| |
| <rule name = "02"> |
| <doc> |
| Streaming applications SHOULD use different channels to select different |
| streaming resolutions. AMQP makes no provision for filtering and/or transforming |
| streams except on the basis of priority-based selective delivery of individual |
| messages. |
| </doc> |
| </rule> |
| |
| <chassis name = "server" implement = "MUST" /> |
| <response name = "consume-ok" /> |
| |
| <field name = "ticket" domain = "access-ticket"> |
| <rule name = "01"> |
| <doc> |
| The client MUST provide a valid access ticket giving "read" access rights to |
| the realm for the queue. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "queue" domain = "queue-name"> |
| <doc> |
| Specifies the name of the queue to consume from. If the queue name is null, |
| refers to the current queue for the channel, which is the last declared queue. |
| </doc> |
| |
| <rule name = "01"> |
| <doc> |
| If the client did not previously declare a queue, and the queue name in this |
| method is empty, the server MUST raise a connection exception with reply |
| code 530 (not allowed). |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "consumer-tag" domain = "consumer-tag"> |
| <doc> |
| Specifies the identifier for the consumer. The consumer tag is local to a |
| connection, so two clients can use the same consumer tags. If this field is |
| empty the server will generate a unique tag. |
| </doc> |
| |
| <rule name = "01"> |
| <!-- TODO: Rule split? --> |
| <doc> |
| The tag MUST NOT refer to an existing consumer. If the client attempts to |
| create two consumers with the same non-empty tag the server MUST raise a |
| connection exception with reply code 530 (not allowed). |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "no-local" domain = "no-local" /> |
| |
| <field name = "exclusive" domain = "bit" label = "request exclusive access"> |
| <doc> |
| Request exclusive consumer access, meaning only this consumer can access the |
| queue. |
| </doc> |
| |
| |
| <!-- Rule test name: was "amq_file_00" --> |
| <rule name = "01"> |
| <doc> |
| If the server cannot grant exclusive access to the queue when asked, - |
| because there are other consumers active - it MUST raise a channel exception |
| with return code 405 (resource locked). |
| </doc> |
| </rule> |
| </field> |
| </method> |
| |
| <method name = "consume-ok" synchronous = "1" index = "21" label = "confirm a new consumer"> |
| <doc> |
| This method provides the client with a consumer tag which it may use in methods that |
| work with the consumer. |
| </doc> |
| |
| <chassis name = "client" implement = "MUST" /> |
| |
| <field name = "consumer-tag" domain = "consumer-tag"> |
| <doc>Holds the consumer tag specified by the client or provided by the server.</doc> |
| </field> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "cancel" synchronous = "1" index = "30" label = "end a queue consumer"> |
| <doc> |
| This method cancels a consumer. Since message delivery is asynchronous the client |
| may continue to receive messages for a short while after canceling a consumer. It |
| may process or discard these as appropriate. |
| </doc> |
| |
| <chassis name = "server" implement = "MUST" /> |
| |
| <response name = "cancel-ok" /> |
| |
| <field name = "consumer-tag" domain = "consumer-tag" /> |
| </method> |
| |
| <method name = "cancel-ok" synchronous = "1" index = "31" label = "confirm a cancelled consumer"> |
| <doc>This method confirms that the cancellation was completed.</doc> |
| |
| <chassis name = "client" implement = "MUST" /> |
| |
| <field name = "consumer-tag" domain = "consumer-tag" /> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "publish" content = "1" index = "40" label = "publish a message"> |
| <doc> |
| This method publishes a message to a specific exchange. The message will be routed |
| to queues as defined by the exchange configuration and distributed to any active |
| consumers as appropriate. |
| </doc> |
| |
| <chassis name = "server" implement = "MUST" /> |
| |
| <field name = "ticket" domain = "access-ticket"> |
| <rule name = "01"> |
| <doc> |
| The client MUST provide a valid access ticket giving "write" access rights |
| to the access realm for the exchange. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "exchange" domain = "exchange-name"> |
| <doc> |
| Specifies the name of the exchange to publish to. The exchange name can be |
| empty, meaning the default exchange. If the exchange name is specified, and that |
| exchange does not exist, the server will raise a channel exception. |
| </doc> |
| |
| <rule name = "01"> |
| <doc> |
| The server MUST accept a blank exchange name to mean the default exchange. |
| </doc> |
| </rule> |
| |
| <rule name = "02"> |
| <doc> |
| If the exchange was declared as an internal exchange, the server MUST |
| respond with a reply code 403 (access refused) and raise a channel |
| exception. |
| </doc> |
| </rule> |
| |
| <rule name = "03"> |
| <doc> |
| The exchange MAY refuse stream content in which case it MUST respond with a |
| reply code 540 (not implemented) and raise a channel exception. |
| </doc> |
| </rule> |
| </field> |
| |
| <field name = "routing-key" domain = "shortstr" label = "Message routing key"> |
| <doc> |
| Specifies the routing key for the message. The routing key is used for routing |
| messages depending on the exchange configuration. |
| </doc> |
| </field> |
| |
| <field name = "mandatory" domain = "bit" label = "indicate mandatory routing"> |
| <doc> |
| This flag tells the server how to react if the message cannot be routed to a |
| queue. If this flag is set, the server will return an unroutable message with a |
| Return method. If this flag is zero, the server silently drops the message. |
| </doc> |
| |
| <!-- Rule test name: was "amq_stream_00" --> |
| <rule name = "01"> |
| <doc>The server SHOULD implement the mandatory flag.</doc> |
| </rule> |
| </field> |
| |
| <field name = "immediate" domain = "bit" label = "request immediate delivery"> |
| <doc> |
| This flag tells the server how to react if the message cannot be routed to a |
| queue consumer immediately. If this flag is set, the server will return an |
| undeliverable message with a Return method. If this flag is zero, the server |
| will queue the message, but with no guarantee that it will ever be consumed. |
| </doc> |
| |
| <!-- Rule test name: was "amq_stream_00" --> |
| <rule name = "01"> |
| <doc>The server SHOULD implement the immediate flag.</doc> |
| </rule> |
| </field> |
| </method> |
| |
| <method name = "return" content = "1" index = "50" label = "return a failed message"> |
| <doc> |
| This method returns an undeliverable message that was published with the "immediate" |
| flag set, or an unroutable message published with the "mandatory" flag set. The |
| reply code and text provide information about the reason that the message was |
| undeliverable. |
| </doc> |
| |
| <chassis name = "client" implement = "MUST" /> |
| |
| <field name = "reply-code" domain = "reply-code" /> |
| |
| <field name = "reply-text" domain = "reply-text" /> |
| |
| <field name = "exchange" domain = "exchange-name"> |
| <doc> |
| Specifies the name of the exchange that the message was originally published to. |
| </doc> |
| </field> |
| |
| <field name = "routing-key" domain = "shortstr" label = "Message routing key"> |
| <doc>Specifies the routing key name specified when the message was published.</doc> |
| </field> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "deliver" content = "1" index = "60" |
| label = "notify the client of a consumer message"> |
| <doc> |
| This method delivers a message to the client, via a consumer. In the asynchronous |
| message delivery model, the client starts a consumer using the Consume method, then |
| the server responds with Deliver methods as and when messages arrive for that |
| consumer. |
| </doc> |
| |
| <chassis name = "client" implement = "MUST" /> |
| |
| <field name = "consumer-tag" domain = "consumer-tag" /> |
| |
| <field name = "delivery-tag" domain = "delivery-tag" /> |
| |
| <field name = "exchange" domain = "exchange-name"> |
| <doc> |
| Specifies the name of the exchange that the message was originally published to. |
| </doc> |
| </field> |
| |
| <field name = "queue" domain = "queue-name"> |
| <doc> |
| Specifies the name of the queue that the message came from. Note that a single |
| channel can start many consumers on different queues. |
| </doc> |
| <assert check = "notnull" /> |
| </field> |
| </method> |
| </class> |
| |
| <!-- == TX =============================================================== --> |
| |
| <class name = "tx" handler = "channel" index = "90" label = "work with standard transactions"> |
| <doc> |
| Standard transactions provide so-called "1.5 phase commit". We can ensure that work is |
| never lost, but there is a chance of confirmations being lost, so that messages may be |
| resent. Applications that use standard transactions must be able to detect and ignore |
| duplicate messages. |
| </doc> |
| |
| <!-- TODO: Rule split? --> |
| |
| <rule name = "01"> |
| <doc> |
| An client using standard transactions SHOULD be able to track all messages received |
| within a reasonable period, and thus detect and reject duplicates of the same |
| message. It SHOULD NOT pass these to the application layer. |
| </doc> |
| </rule> |
| |
| <doc type = "grammar"> |
| tx = C:SELECT S:SELECT-OK |
| / C:COMMIT S:COMMIT-OK |
| / C:ROLLBACK S:ROLLBACK-OK |
| </doc> |
| |
| <chassis name = "server" implement = "SHOULD" /> |
| <chassis name = "client" implement = "MAY" /> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "select" synchronous = "1" index = "10" label = "select standard transaction mode"> |
| <doc> |
| This method sets the channel to use standard transactions. The client must use this |
| method at least once on a channel before using the Commit or Rollback methods. |
| </doc> |
| <chassis name = "server" implement = "MUST" /> |
| <response name = "select-ok" /> |
| </method> |
| |
| <method name = "select-ok" synchronous = "1" index = "11" label = "confirm transaction mode"> |
| <doc> |
| This method confirms to the client that the channel was successfully set to use |
| standard transactions. |
| </doc> |
| <chassis name = "client" implement = "MUST" /> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "commit" synchronous = "1" index = "20" label = "commit the current transaction"> |
| <doc> |
| This method commits all messages published and acknowledged in the current |
| transaction. A new transaction starts immediately after a commit. |
| </doc> |
| <chassis name = "server" implement = "MUST" /> |
| <response name = "commit-ok" /> |
| </method> |
| |
| <method name = "commit-ok" synchronous = "1" index = "21" label = "confirm a successful commit"> |
| <doc> |
| This method confirms to the client that the commit succeeded. Note that if a commit |
| fails, the server raises a channel exception. |
| </doc> |
| <chassis name = "client" implement = "MUST" /> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "rollback" synchronous = "1" index = "30" |
| label = "abandon the current transaction"> |
| <doc> |
| This method abandons all messages published and acknowledged in the current |
| transaction. A new transaction starts immediately after a rollback. |
| </doc> |
| <chassis name = "server" implement = "MUST" /> |
| <response name = "rollback-ok" /> |
| </method> |
| |
| <method name = "rollback-ok" synchronous = "1" index = "31" label = "confirm successful rollback"> |
| <doc> |
| This method confirms to the client that the rollback succeeded. Note that if an |
| rollback fails, the server raises a channel exception. |
| </doc> |
| <chassis name = "client" implement = "MUST" /> |
| </method> |
| </class> |
| |
| <!-- == DTX ============================================================== --> |
| |
| <class name = "dtx" handler = "channel" index = "100" label = "work with distributed transactions"> |
| <doc> |
| Distributed transactions provide so-called "2-phase commit". The AMQP distributed |
| transaction model supports the X-Open XA architecture and other distributed transaction |
| implementations. The Dtx class assumes that the server has a private communications |
| channel (not AMQP) to a distributed transaction coordinator. |
| </doc> |
| |
| <doc type = "grammar"> |
| dtx = C:SELECT S:SELECT-OK |
| C:START S:START-OK |
| </doc> |
| |
| <chassis name = "server" implement = "MAY" /> |
| <chassis name = "client" implement = "MAY" /> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "select" synchronous = "1" index = "10" label = "select standard transaction mode"> |
| <doc> |
| This method sets the channel to use distributed transactions. The client must use |
| this method at least once on a channel before using the Start method. |
| </doc> |
| <chassis name = "server" implement = "MUST" /> |
| <response name = "select-ok" /> |
| </method> |
| |
| <method name = "select-ok" synchronous = "1" index = "11" label = "confirm transaction mode"> |
| <doc> |
| This method confirms to the client that the channel was successfully set to use |
| distributed transactions. |
| </doc> |
| <chassis name = "client" implement = "MUST" /> |
| </method> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "start" synchronous = "1" index = "20" |
| label = "start a new distributed transaction"> |
| <doc> |
| This method starts a new distributed transaction. This must be the first method on a |
| new channel that uses the distributed transaction mode, before any methods that |
| publish or consume messages. |
| </doc> |
| <chassis name = "server" implement = "MAY" /> |
| <response name = "start-ok" /> |
| <field name = "dtx-identifier" domain = "shortstr" label = "transaction identifier"> |
| <doc> |
| The distributed transaction key. This identifies the transaction so that the |
| AMQP server can coordinate with the distributed transaction coordinator. |
| </doc> |
| <assert check = "notnull" /> |
| </field> |
| </method> |
| |
| <method name = "start-ok" synchronous = "1" index = "21" |
| label = "confirm the start of a new distributed transaction"> |
| <doc> |
| This method confirms to the client that the transaction started. Note that if a |
| start fails, the server raises a channel exception. |
| </doc> |
| <chassis name = "client" implement = "MUST" /> |
| </method> |
| </class> |
| |
| <!-- == TUNNEL =========================================================== --> |
| |
| <class name = "tunnel" handler = "tunnel" index = "110" label = "methods for protocol tunneling"> |
| <doc> |
| The tunnel methods are used to send blocks of binary data - which can be serialised AMQP |
| methods or other protocol frames - between AMQP peers. |
| </doc> |
| |
| <doc type = "grammar"> |
| tunnel = C:REQUEST |
| / S:REQUEST |
| </doc> |
| |
| <chassis name = "server" implement = "MAY" /> |
| <chassis name = "client" implement = "MAY" /> |
| |
| <field name = "headers" domain = "table" label = "message header field table" /> |
| <field name = "proxy-name" domain = "shortstr" label = "identity of tunnelling proxy" /> |
| <field name = "data-name" domain = "shortstr" label = "name or type of message being tunnelled" /> |
| <field name = "durable" domain = "octet" label = "message durability indicator" /> |
| <field name = "broadcast" domain = "octet" label = "message broadcast mode" /> |
| |
| <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - --> |
| |
| <method name = "request" content = "1" index = "10" label = "sends a tunnelled method"> |
| <doc> |
| This method tunnels a block of binary data, which can be an encoded |
| AMQP method or other data. The binary data is sent as the content for |
| the Tunnel.Request method. |
| </doc> |
| <chassis name = "server" implement = "MUST" /> |
| <field name = "meta-data" domain = "table" label = "meta data for the tunnelled block"> |
| <doc> |
| This field table holds arbitrary meta-data that the sender needs to |
| pass to the recipient. |
| </doc> |
| </field> |
| </method> |
| </class> |
| </amqp> |