mirror of https://github.com/apache/activemq.git
1859 lines
71 KiB
XML
Executable File
1859 lines
71 KiB
XML
Executable File
<?xml version="1.0"?>
|
|
|
|
<document>
|
|
<description>All JMS requirements as per 1.0.2b of the specification
|
|
</description>
|
|
|
|
<!-- TODO -->
|
|
<!-- . add test for durable subscriber where subscription starts with a
|
|
a selector, but is subsequently changed to no selector -->
|
|
<!-- . likewise for queues -->
|
|
<!-- . verify JMSXDeliveryCount is set/incremented for providers that
|
|
support it -->
|
|
<!-- . verify that JMSXUserID, JMSXAppID, JMSXProducerTXID, JMSXConsumerTXID
|
|
and JMSXRcvTimestamp are set for those providers that support it.
|
|
Also check that these properties are returned by metadata -->
|
|
<!-- . test behaviour of QueueBrowser for connection stop, connection close,
|
|
and session close -->
|
|
<!-- . add coverage of sections 4.4.8 - 4.4.10 -->
|
|
<!-- . add recover test that tests the redelivery flag for messages not
|
|
received earlier (higher priority maybe?) -->
|
|
<!-- . add recover & rollback test that test expiration -->
|
|
<!-- . add coverage of sections 4.4.12 - 4.4.15 -->
|
|
<!-- . add coverage of sections 4.5 - 4.10 -->
|
|
<!-- . add coverage of sections 5, 6 -->
|
|
|
|
<reference referenceId="implied">
|
|
<section name="Undefined" title="An implied requirement"/>
|
|
</reference>
|
|
|
|
<reference referenceId="section.2.10">
|
|
<section name="2.10" title="Request/Reply"/>
|
|
</reference>
|
|
|
|
<reference referenceId="section.3.4.1">
|
|
<section name="3.4.1" title="JMSDestination"/>
|
|
</reference>
|
|
|
|
<reference referenceId="section.3.4.3">
|
|
<section name="3.4.3" title="JMSMessageID"/>
|
|
</reference>
|
|
|
|
<reference referenceId="section.3.4.5">
|
|
<section name="3.4.5" title="JMSCorrelationID"/>
|
|
</reference>
|
|
|
|
<reference referenceId="section.3.4.7">
|
|
<section name="3.4.7" title="JMSRedelivered"/>
|
|
</reference>
|
|
|
|
<reference referenceId="section.3.4.9">
|
|
<section name="3.4.9" title="JMSExpiration"/>
|
|
</reference>
|
|
|
|
<reference referenceId="section.3.4.11">
|
|
<section name="3.4.11" title="How Message Header Values Are Set"/>
|
|
</reference>
|
|
|
|
<reference referenceId="section.3.5.1">
|
|
<section name="3.5.1" title="Property Names" />
|
|
</reference>
|
|
|
|
<reference referenceId="section.3.5.2">
|
|
<section name="3.5.2" title="Property Values" />
|
|
</reference>
|
|
|
|
<reference referenceId="section.3.5.4">
|
|
<section name="3.5.4" title="Property Value Conversion" />
|
|
</reference>
|
|
|
|
<reference referenceId="section.3.5.5">
|
|
<section name="3.5.5" title="Property Values as Objects" />
|
|
</reference>
|
|
|
|
<reference referenceId="section.3.5.6">
|
|
<section name="3.5.6" title="Property Iteration" />
|
|
</reference>
|
|
|
|
<reference referenceId="section.3.5.8">
|
|
<section name="3.5.8" title="Nonexistent Properties" />
|
|
</reference>
|
|
|
|
<reference referenceId="table.3-2">
|
|
<table>3-2</table>
|
|
</reference>
|
|
|
|
<reference referenceId="section.3.5.9">
|
|
<section name="3.5.9" title="JMS Defined Properties" />
|
|
</reference>
|
|
|
|
<reference referenceId="table.3-3">
|
|
<table>3-3</table>
|
|
</reference>
|
|
|
|
<reference referenceId="section.3.8.1.1">
|
|
<section name="3.8.1.1" title="Message Selector Syntax" />
|
|
</reference>
|
|
|
|
<reference referenceId="section.3.8.1.2">
|
|
<section name="3.8.1.2" title="Null Values" />
|
|
</reference>
|
|
|
|
<reference referenceId="section.3.8.1.3">
|
|
<section name="3.8.1.3" title="Special Notes" />
|
|
</reference>
|
|
|
|
<reference referenceId="section.3.11">
|
|
<section name="3.11"
|
|
title="JMS Message Body" />
|
|
</reference>
|
|
|
|
<reference referenceId="section.3.11.3">
|
|
<section name="3.11.3"
|
|
title="Conversions Provided by StreamMessage and MapMessage" />
|
|
</reference>
|
|
|
|
<reference referenceId="section.3.12">
|
|
<section name="3.12"
|
|
title="Provider Implementations of JMS Message Interfaces" />
|
|
</reference>
|
|
|
|
<reference referenceId="section.4.3.1">
|
|
<section name="4.3.1" title="Authentication" />
|
|
</reference>
|
|
|
|
<reference referenceId="section.4.3.2">
|
|
<section name="4.3.2" title="Client Identifier" />
|
|
</reference>
|
|
|
|
<reference referenceId="section.4.3.3">
|
|
<section name="4.3.3" title="Connection Setup" />
|
|
</reference>
|
|
|
|
<reference referenceId="section.4.3.4">
|
|
<section name="4.3.4" title="Pausing Delivery of Incoming Messages" />
|
|
</reference>
|
|
|
|
<reference referenceId="section.4.3.5">
|
|
<section name="4.3.5" title="Closing a Connection" />
|
|
</reference>
|
|
|
|
<reference referenceId="section.4.3.7">
|
|
<section name="4.3.7" title="ConnectionMetaData" />
|
|
</reference>
|
|
|
|
<reference referenceId="section.4.4.1">
|
|
<section name="4.4.1" title="Closing a Session" />
|
|
</reference>
|
|
|
|
<reference referenceId="section.4.4.7">
|
|
<section name="4.4.7" title="Transactions" />
|
|
</reference>
|
|
|
|
<reference referenceId="section.4.4.11">
|
|
<section name="4.4.11" title="Message Acknowledgment" />
|
|
</reference>
|
|
|
|
<reference referenceId="section.6.3">
|
|
<section name="6.3" title="Durable Subscription" />
|
|
</reference>
|
|
|
|
<reference referenceId="section.6.11">
|
|
<section name="6.11" title="Topic Subscriber" />
|
|
</reference>
|
|
|
|
<reference referenceId="section.6.11.1">
|
|
<section name="6.11.1" title="Durable Topic Subscriber" />
|
|
</reference>
|
|
|
|
<reference referenceId="section.7.3">
|
|
<section name="7.3" title="Standard Exceptions" />
|
|
</reference>
|
|
|
|
<reference referenceId="section.8.2.4">
|
|
<section name="8.2.4" title="ConnectionConsumer" />
|
|
</reference>
|
|
|
|
<reference referenceId="table.3-7">
|
|
<table>3-7</table>
|
|
</reference>
|
|
|
|
<reference referenceId="url.message.bytes">
|
|
<url>http://java.sun.com/products/jms/javadoc-102a/javax/jms/BytesMessage.html</url>
|
|
</reference>
|
|
|
|
<reference referenceId="url.message.stream">
|
|
<url>http://java.sun.com/products/jms/javadoc-102a/javax/jms/StreamMessage.html</url>
|
|
</reference>
|
|
|
|
<requirement requirementId="selector.null">
|
|
<description>
|
|
A null message selector indicates that there is no message selector for
|
|
the message consumer.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.empty">
|
|
<description>
|
|
If the value of a message selector is an empty string, the value is
|
|
treated as a null and indicates that there is no message selector for
|
|
the message consumer.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.evaluation.order">
|
|
<description>
|
|
The order of evaluation of a message selector is from left to right
|
|
within precedence level. Parentheses can be used to change this order.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.literal.string">
|
|
<description>
|
|
A string literal is enclosed in single quotes, with an included single
|
|
quote represented by doubled single quote; for example, 'literal' and
|
|
'literal''s'.<br/>
|
|
String literals use the Unicode character encoding.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.literal.exactnumeric">
|
|
<description>
|
|
An exact numeric literal is a numeric value without a decimal point,
|
|
such as 57, -957, +62; numbers in the range of Java long are supported.
|
|
Exact numeric literals use the Java integer literal syntax.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.literal.approxnumeric">
|
|
<description>
|
|
An approximate numeric literal is a numeric value in scientific notation,
|
|
such as 7E3 and -57.9E2, or a numeric value with a decimal, such as 7.,
|
|
-95.7, and +6.2; numbers in the range of Java double are supported.
|
|
Approximate literals use the Java floating-point literal syntax.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.literal.boolean">
|
|
<description>
|
|
A boolean literal is one of TRUE or FALSE.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.identifier.name">
|
|
<description>
|
|
An identifier is an unlimited-length character sequence that must begin
|
|
with a Java identifier start character; all following characters must be
|
|
Java identifier part characters. An identifier start character is any
|
|
character for which the method Character.isJavaIdentifierStart returns
|
|
true. This includes '_' and '$'. An identifier part character is any
|
|
character for which the method Character.isJavaIdentifierPart returns
|
|
true.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.identifier.case">
|
|
<description>
|
|
Identifiers are case sensitive.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.reservedwords">
|
|
<description>
|
|
Identifiers cannot be the words NULL, TRUE, FALSE, NOT, AND, OR, BETWEEN,
|
|
LIKE, IN, IS, or ESCAPE. These are case-insensitive reserved words.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.reservedwords.case">
|
|
<description>
|
|
Reserved words are case-insensitive.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.property.conversion">
|
|
<description>
|
|
The conversions that apply to the get methods for properties do not
|
|
apply when a property is used in a message selector expression. For
|
|
example, suppose you set a property as a string value, as in the
|
|
following:<br/>
|
|
<tt>myMessage.setStringProperty("NumberOfOrders", "2");</tt><br/>
|
|
The following expression in a message selector would evaluate to false,
|
|
because a string cannot be used in an arithmetic expression:
|
|
<tt>"NumberOfOrders > 1"</tt>
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.identifier.header">
|
|
<description>
|
|
Message header field references are restricted to JMSDeliveryMode,
|
|
JMSPriority, JMSMessageID, JMSTimestamp, JMSCorrelationID, and
|
|
JMSType. JMSMessageID, JMSCorrelationID, and JMSType values may be
|
|
null and if so are treated as a NULL value.
|
|
TODO - need to test some of these in code
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.properties.JMSprefixed">
|
|
<description>
|
|
Any name beginning with 'JMSX' is a JMS defined property name.<br/>
|
|
Any name beginning with 'JMS_' is a provider-specific property name.<br/>
|
|
Any name that does not begin with 'JMS' is an application-specific
|
|
property name.<br/>
|
|
NOTE: cannot realistically test JMS_ properties.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.whitespace">
|
|
<description>
|
|
Whitespace is the same as that defined for Java: space, horizontal tab,
|
|
form feed and line terminator.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.expression">
|
|
<description>
|
|
A selector is a conditional expression; a selector that evaluates to true
|
|
matches; a selector that evaluates to false or unknown does not match.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.expression.arithmetic">
|
|
<description>
|
|
Arithmetic expressions are composed of themselves, arithmetic
|
|
operations, identifiers with numeric values, and numeric literals.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.expression.condition">
|
|
<description>
|
|
Conditional expressions are composed of themselves, comparison
|
|
operations, logical operations, identifiers with boolean values, and
|
|
boolean literals.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.operator.logical.precedence">
|
|
<description>
|
|
Logical operators in order of precedence:
|
|
<ul>
|
|
<li>NOT</li>
|
|
<li>AND</li>
|
|
<li>OR</li>
|
|
</ul>
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.operator.comparison.precedence">
|
|
<description>
|
|
Comparison operators in order of precedence:
|
|
<ul>
|
|
<li>=</li>
|
|
<li>></li>
|
|
<li>>=</li>
|
|
<li><</li>
|
|
<li><=</li>
|
|
<li><> (not equal)</li>
|
|
</ul>
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.operator.arithmetic.precedence">
|
|
<description>
|
|
Arithmetic operators in order of precedence are:
|
|
<ul>
|
|
<li>+, - (unary)</li>
|
|
<li>*, / (multiplication and division)</li>
|
|
<li>+, - (addition and subtraction)</li>
|
|
</ul>
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.operator.comparison.types">
|
|
<description>
|
|
Only like type values can be compared. One exception is that it is valid
|
|
to compare exact numeric values and approximate numeric values (the type
|
|
conversion required is defined by the rules of Java numeric promotion).
|
|
If the comparison of non-like type values is attempted, the value of the
|
|
operation is false. If either of the type values evaluates to NULL, the
|
|
value of the expression is unknown.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.comparison.boolean">
|
|
<description>
|
|
Boolean comparison is restricted to = and <>
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.comparison.string">
|
|
<description>
|
|
String comparison is restricted to = and <> Two strings are
|
|
equal if and only if they contain the same sequence of characters.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.operator.between">
|
|
<description>
|
|
BETWEEN expressions are of the form:
|
|
arithmetic-expr1 [NOT] BETWEEN arithmetic-expr2 and arithmetic-expr3
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.operator.in">
|
|
<description>
|
|
IN expressions are of the form:
|
|
identifier [NOT] IN (string-literal1, string-literal2, ...)
|
|
where identifier has a String or NULL value.
|
|
If identifier is NULL, the value of the operation is unknown.
|
|
TODO - add tests where identifier is known to be a non-string value
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.operator.like">
|
|
<description>
|
|
LIKE expressions are of the form:
|
|
identifier [NOT] LIKE pattern-value [ESCAPE escape-character]
|
|
where identifier has a String value; pattern-value is a string literal
|
|
where '_' stands for any single character; '%' stands for any sequence of
|
|
characters, including the empty sequence, and all other characters stand
|
|
for themselves. The optional escape-character is a single-character
|
|
string literal whose character is used to escape the special meaning of
|
|
the '_' and '%' in pattern-value.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.operator.is">
|
|
<description>
|
|
IS expressions are of the form:
|
|
identifier IS [NOT] NULL
|
|
The IS NULL form tests for a null header field value or a missing
|
|
property value.
|
|
The IS NOT NULL form tests for the existence of a non-null header field
|
|
value or property value
|
|
The IS NULL and IS NOT NULL operators convert an unknown header or
|
|
property value into the respective TRUE and FALSE values.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
<referenceId>section.3.8.1.2</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.validation">
|
|
<description>
|
|
JMS providers are required to verify the syntactic correctness of a
|
|
message selector at the time it is presented. A method providing a
|
|
syntactically incorrect selector must result in a JMS
|
|
InvalidSelectorException.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.operator.arithmetic.promotion">
|
|
<description>
|
|
Arithmetic operations must use Java numeric promotion.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.values.null">
|
|
<description>
|
|
Header fields and property values may be NULL. Comparison or arithmetic
|
|
with an unknown value always yields an unknown value.
|
|
</description>
|
|
<referenceId>section.3.8.1.2</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.operator.and">
|
|
<description>
|
|
The AND operator evaluates as follows:
|
|
<table border="1">
|
|
<tr><th>AND</th><td>T</td><td>F</td><td>U</td></tr>
|
|
<tr><td>T</td><td>T</td><td>F</td><td>U</td></tr>
|
|
<tr><td>F</td><td>F</td><td>F</td><td>F</td></tr>
|
|
<tr><td>U</td><td>U</td><td>F</td><td>U</td></tr>
|
|
</table>
|
|
</description>
|
|
<reference>
|
|
<table>3-4</table>
|
|
</reference>
|
|
<referenceId>section.3.8.1.2</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.operator.or">
|
|
<description>
|
|
The OR operator evaluates as follows:
|
|
<table border="1">
|
|
<tr><th>OR</th><td>T</td><td>F</td><td>U</td></tr>
|
|
<tr><td>T</td><td>T</td><td>T</td><td>T</td></tr>
|
|
<tr><td>F</td><td>T</td><td>F</td><td>U</td></tr>
|
|
<tr><td>U</td><td>T</td><td>U</td><td>U</td></tr>
|
|
</table>
|
|
</description>
|
|
<reference>
|
|
<table>3-5</table>
|
|
</reference>
|
|
<referenceId>section.3.8.1.2</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.operator.not">
|
|
<description>
|
|
The NOT operator evaluates as follows:
|
|
<table border="1">
|
|
<tr><th>NOT</th><td></td></tr>
|
|
<tr><td>T</td><td>F</td></tr>
|
|
<tr><td>F</td><td>T</td></tr>
|
|
<tr><td>U</td><td>U</td></tr>
|
|
</table>
|
|
</description>
|
|
<reference>
|
|
<table>3-6</table>
|
|
</reference>
|
|
<referenceId>section.3.8.1.2</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.JMSDeliveryMode">
|
|
<description>
|
|
When used in a message selector JMSDeliveryMode is treated as having the
|
|
values 'PERSISTENT' and 'NON_PERSISTENT'.
|
|
</description>
|
|
<referenceId>section.3.8.1.3</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="selector.datetime">
|
|
<description>
|
|
Date and time values should use the standard Java long millis value.
|
|
When a date or time literal is included in a message selector, it should
|
|
be an integer literal for a millis value.
|
|
</description>
|
|
<referenceId>section.3.8.1.3</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="connection.authentication">
|
|
<description>
|
|
When creating a connection, a client may specify its credentials
|
|
as a name/password.
|
|
JMSSecurityException must be thrown when a provider rejects a
|
|
user name/password submitted by a client
|
|
</description>
|
|
<referenceId>section.4.3.1</referenceId>
|
|
<referenceId>section.7.3</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="connection.clientID.administered">
|
|
<description>
|
|
The facility to explicitly set a connection's client identifier is not a
|
|
mechanism for overriding the identifier that has been administratively
|
|
configured. It is provided for the case where no administratively
|
|
specified identifier exists. If one does exist, an attempt to change it
|
|
by setting it must throw an IllegalStateException.
|
|
</description>
|
|
<referenceId>section.4.3.2</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="connection.method.setClientID">
|
|
<description>
|
|
If a client explicitly sets the client identifer it must do this
|
|
immediately after creating the connection and before any other action on
|
|
the connection is taken. After this point, setting the client identifier
|
|
is a programming error that should throw an IllegalStateException.
|
|
</description>
|
|
<referenceId>section.4.3.2</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="connection.clientID.duplicate">
|
|
<description>
|
|
The client state identified by a client identifier can be in use by only
|
|
one client at a time. A JMS provider must prevent concurrently executing
|
|
clients from using it.
|
|
This prevention may take the form of JMSExceptions thrown when such use
|
|
is attempted; it may result in the offending client being blocked; or
|
|
some other solution. A JMS provider must insure that such attempted
|
|
'sharing' of an individual client state does not result in messages
|
|
being lost or doubly processed.
|
|
TODO - don't handle the blocked scenario
|
|
</description>
|
|
<referenceId>section.4.3.2</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="connection.creation">
|
|
<description>
|
|
When a Connection is created, it is in stopped mode. That means that no
|
|
messages are being delivered to it.
|
|
</description>
|
|
<referenceId>section.4.3.3</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="connection.stopped">
|
|
<description>
|
|
No messages are delivered by a connection to its client until it has been
|
|
started.
|
|
</description>
|
|
<referenceId>section.4.3.3</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="connection.stopped.send">
|
|
<description>
|
|
Stopping a connection has no effect on its ability to send messages.
|
|
</description>
|
|
<referenceId>section.4.3.4</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="connection.stop.listeners">
|
|
<description>
|
|
A stop method call must not return until delivery of messages has paused.
|
|
This means a client can rely on the fact that none of its message
|
|
listeners will be called and all threads of control waiting for receive
|
|
to return will not return with a message until the connection is
|
|
restarted.
|
|
If MessageListeners are running when stop is invoked, stop must wait
|
|
until all of them have returned before it may return. While these
|
|
MessageListeners are completing, they must have the full services of the
|
|
connection available to them.
|
|
TODO - test behaviour of sending messages while a listener is active,
|
|
using a different session (i.e, not from the listener - undefined?)
|
|
TODO - add test where a thread stops a connection and another starts it
|
|
as the stop is in progress.
|
|
</description>
|
|
<referenceId>section.4.3.5</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="connection.stop.receivers">
|
|
<description>
|
|
The receive timers for a stopped connection continue to advance, so
|
|
receives may time out and return a null message while the connection is
|
|
stopped.
|
|
</description>
|
|
<referenceId>section.4.3.5</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="connection.stop.stopped">
|
|
<description>
|
|
Stopping a stopped connection is ignored.
|
|
</description>
|
|
<referenceId>section.4.3.5</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="connection.start.started">
|
|
<description>
|
|
Starting a started connection is ignored.
|
|
</description>
|
|
<referenceId>section.4.3.5</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="connection.close.receivers">
|
|
<description>
|
|
A close terminates all pending message receives on the connection's
|
|
session's consumers. The receives may return with a message or null
|
|
depending on whether or not there was a message available at the time of
|
|
the close.
|
|
</description>
|
|
<referenceId>section.4.3.5</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="connection.close.listeners">
|
|
<description>
|
|
If one or more of the connection's session's message listeners is
|
|
processing a message at the point when connection close is invoked, all
|
|
the facilities of the connection and its sessions must remain available
|
|
to those listeners until they return control to the JMS provider.
|
|
</description>
|
|
<referenceId>section.4.3.5</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="connection.close">
|
|
<description>
|
|
Once a connection has been closed, an attempt to use it or its sessions
|
|
or their message consumers and producers must throw an
|
|
IllegalStateException (calls to the close method of these objects must
|
|
be ignored).
|
|
</description>
|
|
<referenceId>section.4.3.5</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="connection.close.resources">
|
|
<description>
|
|
If a connection is closed, there is no need to close its constituent
|
|
objects. The connection close is sufficient to signal the JMS provider
|
|
that all resources for the connection should be released.
|
|
TODO: probably the only meaningful way to test this in a provider
|
|
independent fashion is to attempt to use a temporary destination created
|
|
by the closed connection, on another connection. This should throw
|
|
InvalidDestinationException?
|
|
</description>
|
|
<referenceId>section.4.3.5</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="connection.close.session.transacted">
|
|
<description>
|
|
Closing a connection must roll back the transactions in progress on its
|
|
transacted sessions.
|
|
</description>
|
|
<referenceId>section.4.3.5</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="connection.close.session.CLIENT_ACKNOWLEDGE">
|
|
<description>
|
|
Closing a connection does NOT force an acknowledgement of
|
|
client-acknowledged sessions.
|
|
</description>
|
|
<referenceId>section.4.3.5</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="connection.close.message">
|
|
<description>
|
|
It is valid to continue to use message objects created or received after
|
|
a connection has been closed with the exception of a received message's
|
|
acknowledge method.
|
|
Invoking the acknowledge method of a received message must throw an
|
|
IllegalStateException.
|
|
</description>
|
|
<referenceId>section.4.3.5</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="connection.close.closed">
|
|
<description>
|
|
Closing a closed connection must NOT throw an exception.
|
|
</description>
|
|
<referenceId>section.4.3.5</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="session.close.transacted">
|
|
<description>
|
|
Closing a transacted session must roll back its transaction in progress.
|
|
</description>
|
|
<referenceId>section.4.4.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="session.close.CLIENT_ACKNOWLEDGE">
|
|
<description>
|
|
Closing a client-acknowledged session does NOT force an acknowledge.
|
|
</description>
|
|
<referenceId>section.4.4.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="session.close">
|
|
<description>
|
|
Once a session has been closed, an attempt to use it or its message
|
|
consumers and producers must throw an IllegalStateException (calls to
|
|
the close method of these objects must be ignored).
|
|
</description>
|
|
<referenceId>section.4.4.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="session.close.message">
|
|
<description>
|
|
It is valid to continue to use message objects created or received via
|
|
the session, with the exception of a received message'acknowledge method.
|
|
Invoking the acknowledge method of a received message must throw an
|
|
IllegalStateException.
|
|
</description>
|
|
<referenceId>section.4.4.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="session.close.closed">
|
|
<description>
|
|
Closing a closed session must NOT throw an exception.
|
|
</description>
|
|
<referenceId>section.4.4.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="session.close.receivers">
|
|
<description>
|
|
A close terminates all pending message receives on the connection's
|
|
session's consumers. The receives may return with a message or null
|
|
depending on whether or not there was a message available at the time of
|
|
the close.
|
|
</description>
|
|
<referenceId>section.4.4.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="session.close.listeners">
|
|
<description>
|
|
If one or more of the connection's session's message listeners is
|
|
processing a message at the point when connection close is invoked, all
|
|
the facilities of the connection and its sessions must remain available
|
|
to those listeners until they return control to the JMS provider.
|
|
</description>
|
|
<referenceId>section.4.4.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="session.transactions">
|
|
<description>
|
|
Each transacted session supports a single series of transactions.
|
|
Each transaction groups a set of produced messages and a set of consumed
|
|
messages into an atomic unit of work.
|
|
In effect, transactions organize a session's input message stream and
|
|
output message stream into series of atomic units. When a transaction
|
|
commits, its atomic unit of input is acknowledged and its associated
|
|
atomic unit of output is sent.
|
|
</description>
|
|
<referenceId>section.4.4.7</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="session.rollback">
|
|
<description>
|
|
If a transacted session is rolled back, its produced messages are
|
|
destroyed and its consumed messages are automatically recovered.
|
|
</description>
|
|
<referenceId>section.4.4.7</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="session.DUPS_OK_ACKNOWLEDGE">
|
|
<description>
|
|
With the DUPS_OK_ACKNOWLEDGE session acknowledgement mode, the session
|
|
lazily acknowledges the delivery of messages. This is likely to result
|
|
in the delivery of some duplicate messages if JMS fails, so it should be
|
|
used only by consumers that are tolerant of duplicate messages. Its
|
|
benefit is the reduction of session overhead achieved by minimizing the
|
|
work the session does to prevent duplicates.
|
|
</description>
|
|
<referenceId>section.4.4.11</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="session.AUTO_ACKNOWLEDGE">
|
|
<description>
|
|
With the AUTO_ACKNOWLEDGE session acknowledgement mode, the session
|
|
automatically acknowledges a client's receipt of a message when it has
|
|
either successfully returned from a call to receive or the
|
|
MessageListener it has called to process the message successfully
|
|
returns.
|
|
</description>
|
|
<referenceId>section.4.4.11</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="session.CLIENT_ACKNOWLEDGE">
|
|
<description>
|
|
With the CLIENT_ACKNOWLEDGE session acknowledgement mode, a client
|
|
acknowledges a message by calling the message's acknowledge method.
|
|
Acknowledging a consumed message automatically acknowledges the receipt
|
|
of all messages that have been delivered by its session.
|
|
</description>
|
|
<referenceId>section.4.4.11</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="session.recover">
|
|
<description>
|
|
A session's recover method is used to stop a session and restart it with
|
|
its first unacknowledged message. In effect, the session's series of
|
|
delivered messages is reset to the point after its last acknowledged
|
|
message. The messages it now delivers may be different from those that
|
|
were originally delivered due to message expiration and the arrival of
|
|
higher-priority messages.<br/>
|
|
A session must set the redelivered flag of messages it redelivers due to
|
|
a recovery.
|
|
</description>
|
|
<referenceId>section.4.4.11</referenceId>
|
|
<referenceId>section.3.4.7</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="session.transactions.transactioninprogress">
|
|
<description>
|
|
A TransactionInProgressException exception is thrown when an operation
|
|
is invalid because a transaction is in progress. For instance,
|
|
attempting to call Session.commit() when a session is part of a
|
|
distributed transaction.
|
|
</description>
|
|
<referenceId>section.7.3</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="session.transactions.commitrolledback">
|
|
<description>
|
|
A TransactionRolledBackException exception must be thrown when a call to
|
|
Session.commit() results in a rollback of the current transaction.
|
|
</description>
|
|
<referenceId>section.7.3</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="session.ack.closedconsumer">
|
|
<description>
|
|
A message can be acknowledged after its message consumer has closed as
|
|
message acknowledgement is performed at the session level
|
|
TODO - need to test this for single message acknowledgement via
|
|
CLIENT_ACKWNOWLEDGE etc
|
|
</description>
|
|
<reference>
|
|
<url>http://java.sun.com/products/jms/faq.html#msg_ack_close</url>
|
|
</reference>
|
|
</requirement>
|
|
|
|
<requirement requirementId="session.listener.serialization">
|
|
<description>
|
|
A session serializes all asynchronous delivery of messages.
|
|
While the session is busy executing one listener, all other messages to
|
|
be asynchronously delivered to the session must wait.
|
|
</description>
|
|
<reference>
|
|
<section name="4.4.14" title="Serial Execution of Client Code" />
|
|
</reference>
|
|
</requirement>
|
|
|
|
<requirement requirementId="session.commit.IllegalStateException">
|
|
<description>
|
|
Invoking commit() on a non-transacted session should throw
|
|
IllegalStateException
|
|
</description>
|
|
<reference>
|
|
<url>http://java.sun.com/products/jms/javadoc-102a/javax/jms/Session.html#commit()</url>
|
|
</reference>
|
|
<referenceId>section.7.3</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="session.rollback.IllegalStateException">
|
|
<description>
|
|
Invoking rollback() on a non-transacted session should throw
|
|
IllegalStateException
|
|
</description>
|
|
<reference>
|
|
<url>http://java.sun.com/products/jms/javadoc-102a/javax/jms/Session.html#rollback()</url>
|
|
</reference>
|
|
</requirement>
|
|
|
|
<requirement requirementId="session.recover.IllegalStateException">
|
|
<description>
|
|
Invoking recover() on a transacted session should throw
|
|
IllegalStateException
|
|
</description>
|
|
<reference>
|
|
<url>http://java.sun.com/products/jms/javadoc-102a/javax/jms/Session.html#recover()</url>
|
|
</reference>
|
|
</requirement>
|
|
|
|
<requirement requirementId="producer.ttl.default">
|
|
<description>
|
|
If not specified, the default time-to-live for a producer equals
|
|
<code>0</code>
|
|
</description>
|
|
<reference>
|
|
<url>http://java.sun.com/products/jms/javadoc-102a/javax/jms/MessageProducer.html#getTimeToLive()</url>
|
|
</reference>
|
|
<reference>
|
|
<url>http://java.sun.com/products/jms/javadoc-102a/javax/jms/MessageProducer.html#setTimeToLive()</url>
|
|
</reference>
|
|
</requirement>
|
|
|
|
<requirement requirementId="producer.ttl.set">
|
|
<description>
|
|
A client can specify a default time-to-live for messages sent by a
|
|
message producer, to be used when a time-to-live isn't specified per
|
|
message.
|
|
<p>
|
|
<strong>Note:</strong> the specification doesn't mention min or max
|
|
values for time-to-live, or if any exceptions will be thrown if
|
|
an invalid time-to-live is specified.
|
|
</p>
|
|
</description>
|
|
<reference>
|
|
<url>http://java.sun.com/products/jms/javadoc-102a/javax/jms/MessageProducer.html</url>
|
|
</reference>
|
|
<reference>
|
|
<url>http://java.sun.com/products/jms/javadoc-102a/javax/jms/TopicPublisher.html#publish(javax.jms.Message)</url>
|
|
</reference>
|
|
<reference>
|
|
<url>http://java.sun.com/products/jms/javadoc-102a/javax/jms/TopicPublisher.html#publish(javax.jms.Topic,%20javax.jms.Message)</url>
|
|
</reference>
|
|
<reference>
|
|
<url>http://java.sun.com/products/jms/javadoc-102a/javax/jms/QueueSender.html#send(javax.jms.Message)</url>
|
|
</reference>
|
|
<reference>
|
|
<url>http://java.sun.com/products/jms/javadoc-102a/javax/jms/QueueSender.html#send(javax.jms.Queue,%20javax.jms.Message)</url>
|
|
</reference>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.destination">
|
|
<description>
|
|
When a message is sent, JMSDestination is ignored. After completion of
|
|
the send it holds the destination object specified by the sending method.
|
|
When a message is received, its destination value must be equivalent to
|
|
the value assigned when it was sent.
|
|
</description>
|
|
<referenceId>section.3.4.1</referenceId>
|
|
<referenceId>section.3.4.11</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.identifier">
|
|
<description>
|
|
When a message is sent, JMSMessageID is ignored. When the send method
|
|
returns it contains a provider-assigned value.
|
|
</description>
|
|
<referenceId>section.3.4.3</referenceId>
|
|
<referenceId>section.3.4.11</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.identifier.prefix">
|
|
<description>
|
|
All JMSMessageID values must start with the prefix 'ID:'
|
|
</description>
|
|
<referenceId>section.3.4.3</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.correlation">
|
|
<description>
|
|
The JMSCorrelationID header field may be used to link one message with
|
|
another. It can contain a provider-specific message ID, an
|
|
application-specific string, or a provider-native byte[] value.
|
|
The application-specific string must not start with the 'ID:' prefix:
|
|
this is reserved for provider generated messages Ids.
|
|
</description>
|
|
<referenceId>section.2.10</referenceId>
|
|
<referenceId>section.3.4.5</referenceId>
|
|
<referenceId>section.3.4.11</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.correlation.bytes" optional="true">
|
|
<description>
|
|
If a provider supports the native concept of correlation ID, a JMS
|
|
client may need to assign specific JMSCorrelationID values to match
|
|
those expected by non-JMS clients. A byte[] value is used for this
|
|
purpose. JMS providers without native correlation ID values are not
|
|
required to support byte[] values - in this case
|
|
setJMSCorrelationIDAsBytes() and getJMSCorrelationIDAsBytes() may throw
|
|
java.lang.UnsupportedOperationException.
|
|
</description>
|
|
<referenceId>section.3.4.5</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.redelivered.receive">
|
|
<description>
|
|
If a client receives a message with the JMSRedelivered indicator set, it
|
|
is likely, but not guaranteed, that this message was delivered but not
|
|
acknowledged in the past. In general, a provider must set the
|
|
JMSRedelivered message header field of a message whenever it is
|
|
redelivering a message.
|
|
</description>
|
|
<referenceId>section.3.4.7</referenceId>
|
|
<referenceId>section.3.4.11</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.redelivered.send">
|
|
<description>
|
|
The JMSRedelivered header field has no meaning on send and is left
|
|
unassigned by the sending method.
|
|
</description>
|
|
<referenceId>section.3.4.7</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.expiration.send">
|
|
<description>
|
|
When a message is sent, its expiration time is calculated as the sum of
|
|
the time-to-live value specified on the send method and the current GMT
|
|
value. On return from the send method, the message's JMSExpiration header
|
|
field contains this value.
|
|
</description>
|
|
<referenceId>section.3.4.9</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.expiration.receive">
|
|
<description>
|
|
When a message is received its JMSExpiration header field contains the
|
|
expiration as that on send.
|
|
</description>
|
|
<referenceId>section.3.4.9</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.expiration.zero">
|
|
<description>
|
|
If the time-to-live is specified as zero, expiration is set to zero to
|
|
indicate that the message does not expire.
|
|
</description>
|
|
<referenceId>section.3.4.9</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.expiration.expired">
|
|
<description>
|
|
When GMT is later than an undelivered message's expiration time, the
|
|
message should be destroyed.
|
|
Clients should not receive messages that have expired; however, JMS does
|
|
not guarantee that this will not happen.
|
|
</description>
|
|
<referenceId>section.3.4.9</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.replyTo">
|
|
<description>
|
|
The JMSReplyTo header field contains a Destination supplied by a client
|
|
when a message is sent. It is the destination where a reply to the
|
|
message should be sent.<br/>
|
|
Messages sent with a null JMSReplyTo value may be a notification of some
|
|
event or they may just be some data the sender thinks is of interest.
|
|
</description>
|
|
<referenceId>section.2.10</referenceId>
|
|
<reference>
|
|
<section name="3.4.6" title="JMSReplyTo" />
|
|
</reference>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.creation">
|
|
<description>
|
|
When a message is created, its message body and properties may be set.
|
|
</description>
|
|
<reference>
|
|
<section name="3.3" title="JMS Messages" />
|
|
</reference>
|
|
</requirement>
|
|
|
|
<requirement requirementId="properties.identifier">
|
|
<description>
|
|
An identifier is an unlimited-length character sequence that must begin
|
|
with a Java identifier start character; all following characters must be
|
|
Java identifier part characters. An identifier start character is any
|
|
character for which the method Character.isJavaIdentifierStart returns
|
|
true. An identifier part character is any character for which the
|
|
method Character.isJavaIdentifierPart returns true.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="properties.identifier.reserved">
|
|
<description>
|
|
Identifiers cannot be the words NULL, TRUE, FALSE, NOT, AND, OR, BETWEEN,
|
|
LIKE, IN, IS, or ESCAPE. These are case-insensitive reserved words.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="properties.identifier.case">
|
|
<description>
|
|
Identifiers are case sensitive.
|
|
</description>
|
|
<referenceId>section.3.8.1.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="properties.types">
|
|
<description>
|
|
Property values can be boolean, byte, short, int, long, float, double,
|
|
and String.
|
|
</description>
|
|
<referenceId>section.3.5.2</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="properties.objects">
|
|
<description>
|
|
The setObjectProperty method accepts values of Boolean, Byte, Short,
|
|
Integer, Long, Float, Double and String. An attempt to use any other
|
|
class must throw a JMS MessageFormatException.<br/>
|
|
The getObjectProperty method only returns values of null, Boolean, Byte,
|
|
Short, Integer, Long, Float, Double and String. A null value is returned
|
|
if a property by the specified name does not exist.
|
|
</description>
|
|
<referenceId>section.3.5.5</referenceId>
|
|
<referenceId>section.3.5.8</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="properties.integrity">
|
|
<description>
|
|
User properties may not be modified by the provider
|
|
</description>
|
|
<referenceId>implied</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="properties.conversion">
|
|
<description>
|
|
Properties support the following conversion table. The marked cases must
|
|
be supported. The unmarked cases must throw the JMS
|
|
MessageFormatException.<br/>
|
|
The String to numeric conversions must throw the
|
|
java.lang.NumberFormatException if the numeric's valueOf() method does
|
|
not accept the String value as a valid representation.
|
|
A value set as the row type can be read as the column type.<br/>
|
|
<table border="1">
|
|
<tr>
|
|
<th> </th><th>boolean</th><th>byte</th><th>short</th>
|
|
<th>int</th><th>long</th><th>float</th><th>double</th><th>String</th>
|
|
</tr>
|
|
<tr>
|
|
<th>boolean</th>
|
|
<td><b>X</b></td><td> </td><td> </td><td> </td>
|
|
<td> </td><td> </td><td> </td><td><b>X</b></td>
|
|
</tr>
|
|
<tr>
|
|
<th>byte</th><td> </td><td><b>X</b></td><td><b>X</b></td>
|
|
<td><b>X</b></td><td><b>X</b></td><td> </td><td> </td>
|
|
<td><b>X</b></td>
|
|
</tr>
|
|
<tr>
|
|
<th>short</th><td> </td><td> </td><td><b>X</b></td>
|
|
<td><b>X</b></td><td><b>X</b></td><td> </td><td> </td>
|
|
<td><b>X</b></td>
|
|
</tr>
|
|
<tr>
|
|
<th>int</th><td> </td><td> </td><td> </td>
|
|
<td><b>X</b></td><td><b>X</b></td><td> </td><td> </td>
|
|
<td><b>X</b></td>
|
|
</tr>
|
|
<tr>
|
|
<th>long</th><td> </td><td> </td><td> </td>
|
|
<td> </td><td><b>X</b></td><td> </td><td> </td>
|
|
<td><b>X</b></td>
|
|
</tr>
|
|
<tr>
|
|
<th>float</th><td> </td><td> </td><td> </td>
|
|
<td> </td><td> </td><td><b>X</b></td><td><b>X</b></td>
|
|
<td><b>X</b></td>
|
|
</tr>
|
|
<tr>
|
|
<th>double</th><td> </td><td> </td><td> </td>
|
|
<td> </td><td> </td><td> </td><td><b>X</b></td>
|
|
<td><b>X</b></td>
|
|
</tr>
|
|
<tr>
|
|
<th>String</th><td><b>X</b></td><td><b>X</b></td><td><b>X</b></td>
|
|
<td><b>X</b></td><td><b>X</b></td><td><b>X</b></td><td><b>X</b></td>
|
|
<td><b>X</b></td>
|
|
</tr>
|
|
</table>
|
|
</description>
|
|
<referenceId>section.3.5.4</referenceId>
|
|
<referenceId>table.3-2</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="properties.conversion.null">
|
|
<description>
|
|
Attempting to read a null value as a Java primitive type must be treated
|
|
as calling the primitive's corresponding valueOf(String) conversion
|
|
method with a null value.
|
|
</description>
|
|
<referenceId>section.3.5.4</referenceId>
|
|
<referenceId>section.3.5.8</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="properties.method.getPropertyNames">
|
|
<description>
|
|
The order of property values is not defined. To iterate through a
|
|
message's property values, use getPropertyNames to retrieve a property
|
|
name enumeration and then use the various property get methods to
|
|
retrieve their values.
|
|
The getPropertyNames method does not return the names of the JMS standard
|
|
header fields.
|
|
</description>
|
|
<referenceId>section.3.5.6</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.send">
|
|
<description>
|
|
After sending a message, a client may retain and modify it without
|
|
affecting the message that has been sent. The same message object may be
|
|
sent multiple times.
|
|
</description>
|
|
<reference>
|
|
<section name="3.9" title="Access to sent messages" />
|
|
</reference>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.receive">
|
|
<description>
|
|
When a message is received its body is read only. If an attempt is made
|
|
to change them, a MessageNotWriteableException must be thrown.
|
|
If its properties or body are subsequently cleared, they are in the same
|
|
state as a newly created message.
|
|
TODO - need to test in transaction context
|
|
</description>
|
|
<reference>
|
|
<section name="3.5.3" title="Using Properties" />
|
|
</reference>
|
|
<reference>
|
|
<section name="3.10" title="Changing the Value of a Received Message" />
|
|
</reference>
|
|
<reference>
|
|
<section name="3.11.2" title="Read-Only Message Body" />
|
|
</reference>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.method.clearBody">
|
|
<description>
|
|
The clearBody method of Message resets the value of the message body to
|
|
the empty initial message value as set by the message type's create method
|
|
provided by Session. Clearing a message's body does not clear its property
|
|
entries. When a message is cleared, its message body and properties may
|
|
be set.
|
|
</description>
|
|
<reference>
|
|
<section name="3.11.1" title="Clearing a message body" />
|
|
</reference>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.method.clearProperties">
|
|
<description>
|
|
Clearing a message's properties leaves the message with an empty set of
|
|
properties. New property entries can then be both created and read.
|
|
Clearing a message's property entries does not clear the value of its
|
|
body.
|
|
</description>
|
|
<reference>
|
|
<section name="3.5.7" title="Clearing a Message's Property Values" />
|
|
</reference>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.bytes.creation">
|
|
<description>
|
|
When the message is first created, the body of the message is in
|
|
write-only mode. If a client attempts to read a message in write-only
|
|
mode, a MessageNotReadableException is thrown.
|
|
</description>
|
|
<referenceId>url.message.bytes</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.bytes.eof">
|
|
<description>
|
|
MessageEOFException must be thrown when an unexpected end of stream has
|
|
been reached when a message is being read.
|
|
</description>
|
|
<referenceId>section.7.3</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.object.method.setObject">
|
|
<description>
|
|
The setObject method places a copy of the input in the message.
|
|
</description>
|
|
<reference>
|
|
<section name="11.2.21" title="JMS Source JavaDoc Clarifications"/>
|
|
</reference>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.stream.creation">
|
|
<description>
|
|
When the message is first created, the body of the message is in
|
|
write-only mode. If a client attempts to read a message in write-only
|
|
mode, a MessageNotReadableException is thrown.
|
|
</description>
|
|
<referenceId>url.message.stream</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.stream.eof">
|
|
<description>
|
|
MessageEOFException must be thrown when an unexpected end of stream has
|
|
been reached when a message is being read.
|
|
</description>
|
|
<referenceId>section.7.3</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.bytes.read">
|
|
<description>
|
|
If a read method of a BytesMessage throws a MessageFormatException or
|
|
NumberFormatException, the current position of the read pointer must not
|
|
be incremented. A subsequent read must be capable of recovering from the
|
|
exception by re-reading the data as a different type.<br/>
|
|
NOTE: With the exception of the readUTF() method, it is difficult to
|
|
conceive test cases for read methods.
|
|
<ul>
|
|
<li>
|
|
A provider that implements BytesMessage using a DataInputStream
|
|
or equivalent, is likely to only throw MessageFormatException for
|
|
the readUTF() method.<br/>
|
|
The other likely exceptions are MessageEOFException for stream
|
|
overruns, and JMSException for any other error.
|
|
</li>
|
|
<li>
|
|
As BytesMessage does not support conversion, NumberFormatException
|
|
is unlikely to be thrown.
|
|
</li>
|
|
</ul>
|
|
</description>
|
|
<referenceId>section.3.11.3</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.stream.read">
|
|
<description>
|
|
If a read method of a StreamMessage throws a MessageFormatException or
|
|
NumberFormatException, the current position of the read pointer must not
|
|
be incremented. A subsequent read must be capable of recovering from the
|
|
exception by re-reading the data as a different type.
|
|
</description>
|
|
<referenceId>section.3.11.3</referenceId>
|
|
<referenceId>table.3-7</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.map">
|
|
<description>
|
|
A MapMessage is a message whose body contains a set of name-value pairs
|
|
where names are Strings and values are Java primitive types. The entries
|
|
can be accessed sequentially by enumerator or randomly by name. The
|
|
order of the entries is undefined.
|
|
</description>
|
|
<referenceId>section.3.11</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.map.conversion">
|
|
<description>
|
|
MapMessage supports the following conversion table.
|
|
The marked cases must be supported. The unmarked cases must throw a JMS
|
|
MessageFormatException. The String to numeric conversions must throw a
|
|
java.lang.NumberFormatException if the numeric's valueOf() method does
|
|
not accept the String value as a valid representation.
|
|
MapMessage must implement the String to boolean conversion as
|
|
specified by the valueOf(String) method of Boolean as defined by the
|
|
Java language.<br/>
|
|
A value written as the row type can be read as the column type.<br/>
|
|
<table border="1">
|
|
<tr>
|
|
<th> </th><th>boolean</th><th>byte</th><th>short</th>
|
|
<th>char</th><th>int</th><th>long</th><th>float</th><th>double</th>
|
|
<th>String</th><th>byte[]</th>
|
|
</tr>
|
|
<tr>
|
|
<th>boolean</th>
|
|
<td><b>X</b></td><td> </td><td> </td><td> </td>
|
|
<td> </td><td> </td><td> </td><td> </td>
|
|
<td><b>X</b></td><td> </td>
|
|
</tr>
|
|
<tr>
|
|
<th>byte</th><td> </td><td><b>X</b></td><td><b>X</b></td>
|
|
<td> </td><td><b>X</b></td><td><b>X</b></td><td> </td>
|
|
<td> </td><td><b>X</b></td><td> </td>
|
|
</tr>
|
|
<tr>
|
|
<th>short</th><td> </td><td> </td><td><b>X</b></td>
|
|
<td> </td><td><b>X</b></td><td><b>X</b></td><td> </td>
|
|
<td> </td><td><b>X</b></td><td> </td>
|
|
</tr>
|
|
<tr>
|
|
<th>char</th><td> </td><td> </td><td> </td>
|
|
<td><b>X</b></td><td> </td><td> </td><td> </td>
|
|
<td> </td><td><b>X</b></td><td> </td>
|
|
</tr>
|
|
<tr>
|
|
<th>int</th><td> </td><td> </td><td> </td>
|
|
<td> </td><td><b>X</b></td><td><b>X</b></td><td> </td>
|
|
<td> </td><td><b>X</b></td><td> </td>
|
|
</tr>
|
|
<tr>
|
|
<th>long</th><td> </td><td> </td><td> </td>
|
|
<td> </td><td> </td><td><b>X</b></td><td> </td>
|
|
<td> </td><td><b>X</b></td><td> </td>
|
|
</tr>
|
|
<tr>
|
|
<th>float</th><td> </td><td> </td><td> </td>
|
|
<td> </td><td> </td><td> </td><td><b>X</b></td>
|
|
<td><b>X</b></td><td><b>X</b></td><td> </td>
|
|
</tr>
|
|
<tr>
|
|
<th>double</th><td> </td><td> </td><td> </td>
|
|
<td> </td><td> </td><td> </td><td> </td>
|
|
<td><b>X</b></td><td><b>X</b></td><td> </td>
|
|
</tr>
|
|
<tr>
|
|
<th>String</th><td><b>X</b></td><td><b>X</b></td><td><b>X</b></td>
|
|
<td> </td><td><b>X</b></td><td><b>X</b></td><td><b>X</b></td>
|
|
<td><b>X</b></td><td><b>X</b></td><td> </td>
|
|
</tr>
|
|
<tr>
|
|
<th>byte[]</th><td> </td><td> </td><td> </td>
|
|
<td> </td><td> </td><td> </td><td> </td>
|
|
<td> </td><td> </td><td><b>X</b></td>
|
|
</tr>
|
|
</table>
|
|
</description>
|
|
<referenceId>section.3.11.3</referenceId>
|
|
<referenceId>table.3-7</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.map.null">
|
|
<description>
|
|
For MapMessage, attempting to read a null value as a Java primitive
|
|
type must be treated as calling the primitive's corresponding
|
|
valueOf(String) conversion method with a null value. Since char does not
|
|
support a String conversion, attempting to read a null value as a char
|
|
must throw NullPointerException.
|
|
</description>
|
|
<referenceId>section.3.11.3</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.map.unset">
|
|
<description>
|
|
Getting a MapMessage field for a field name that has not been set is
|
|
handled as if the field exists with a null value.
|
|
</description>
|
|
<referenceId>section.3.11.3</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.stream.conversion">
|
|
<description>
|
|
StreamMessage supports the following conversion table.
|
|
The marked cases must be supported. The unmarked cases must throw a JMS
|
|
MessageFormatException. The String to numeric conversions must throw a
|
|
java.lang.NumberFormatException if the numeric's valueOf() method does
|
|
not accept the String value as a valid representation.
|
|
StreamMessage must implement the String to boolean conversion as
|
|
specified by the valueOf(String) method of Boolean as defined by the
|
|
Java language.<br/>
|
|
A value written as the row type can be read as the column type.<br/>
|
|
<table border="1">
|
|
<tr>
|
|
<th> </th><th>boolean</th><th>byte</th><th>short</th>
|
|
<th>char</th><th>int</th><th>long</th><th>float</th><th>double</th>
|
|
<th>String</th><th>byte[]</th>
|
|
</tr>
|
|
<tr>
|
|
<th>boolean</th>
|
|
<td><b>X</b></td><td> </td><td> </td><td> </td>
|
|
<td> </td><td> </td><td> </td><td> </td>
|
|
<td><b>X</b></td><td> </td>
|
|
</tr>
|
|
<tr>
|
|
<th>byte</th><td> </td><td><b>X</b></td><td><b>X</b></td>
|
|
<td> </td><td><b>X</b></td><td><b>X</b></td><td> </td>
|
|
<td> </td><td><b>X</b></td><td> </td>
|
|
</tr>
|
|
<tr>
|
|
<th>short</th><td> </td><td> </td><td><b>X</b></td>
|
|
<td> </td><td><b>X</b></td><td><b>X</b></td><td> </td>
|
|
<td> </td><td><b>X</b></td><td> </td>
|
|
</tr>
|
|
<tr>
|
|
<th>char</th><td> </td><td> </td><td> </td>
|
|
<td><b>X</b></td><td> </td><td> </td><td> </td>
|
|
<td> </td><td><b>X</b></td><td> </td>
|
|
</tr>
|
|
<tr>
|
|
<th>int</th><td> </td><td> </td><td> </td>
|
|
<td> </td><td><b>X</b></td><td><b>X</b></td><td> </td>
|
|
<td> </td><td><b>X</b></td><td> </td>
|
|
</tr>
|
|
<tr>
|
|
<th>long</th><td> </td><td> </td><td> </td>
|
|
<td> </td><td> </td><td><b>X</b></td><td> </td>
|
|
<td> </td><td><b>X</b></td><td> </td>
|
|
</tr>
|
|
<tr>
|
|
<th>float</th><td> </td><td> </td><td> </td>
|
|
<td> </td><td> </td><td> </td><td><b>X</b></td>
|
|
<td><b>X</b></td><td><b>X</b></td><td> </td>
|
|
</tr>
|
|
<tr>
|
|
<th>double</th><td> </td><td> </td><td> </td>
|
|
<td> </td><td> </td><td> </td><td> </td>
|
|
<td><b>X</b></td><td><b>X</b></td><td> </td>
|
|
</tr>
|
|
<tr>
|
|
<th>String</th><td><b>X</b></td><td><b>X</b></td><td><b>X</b></td>
|
|
<td> </td><td><b>X</b></td><td><b>X</b></td><td><b>X</b></td>
|
|
<td><b>X</b></td><td><b>X</b></td><td> </td>
|
|
</tr>
|
|
<tr>
|
|
<th>byte[]</th><td> </td><td> </td><td> </td>
|
|
<td> </td><td> </td><td> </td><td> </td>
|
|
<td> </td><td> </td><td><b>X</b></td>
|
|
</tr>
|
|
</table>
|
|
</description>
|
|
<referenceId>section.3.11.3</referenceId>
|
|
<referenceId>table.3-7</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.map.case">
|
|
<description>
|
|
MapMessage field names are case sensitive.<br/>
|
|
NOTE: the specification does not explicitly mention this requirement,
|
|
but it is in keeping with property name requirements.
|
|
</description>
|
|
<referenceId>implied</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.stream.null">
|
|
<description>
|
|
For StreamMessage, attempting to read a null value as a Java primitive
|
|
type must be treated as calling the primitive's corresponding
|
|
valueOf(String) conversion method with a null value. Since char does not
|
|
support a String conversion, attempting to read a null value as a char
|
|
must throw NullPointerException.<br/>
|
|
NOTE: the specification is not explicit on the behaviour of invoking
|
|
writeBytes() or writeString() with a null value, but an acceptable policy
|
|
is to throw a NullPointerException. This is in keeping with the behaviour
|
|
of DataOutputStream.
|
|
</description>
|
|
<referenceId>section.3.11.3</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.foreign">
|
|
<description>
|
|
A provider must be prepared to accept, from a client, a
|
|
message whose implementation is not one of its own.
|
|
A message with a 'foreign' implementation may not be handled as
|
|
efficiently as a provider's own implementation; however, it must be
|
|
handled.<br/>
|
|
Note that if the foreign message implementation contains a
|
|
<em>JMSReplyTo</em> header field that is set to a foreign destination
|
|
implementation, the provider is not required to handle or preserve the
|
|
value of this field.
|
|
</description>
|
|
<referenceId>section.3.12</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.copy">
|
|
<description>
|
|
The JMS message interfaces provide read/get methods for accessing
|
|
objects in a message body. All of these methods must be implemented to
|
|
return a copy of the accessed objects.
|
|
</description>
|
|
<referenceId>section.3.12</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="properties.copy">
|
|
<description>
|
|
The JMS message interfaces provide read/get methods for accessing
|
|
message object properties. All of these methods must be implemented to
|
|
return a copy of the accessed objects.
|
|
</description>
|
|
<referenceId>section.3.12</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.bytes.method.clearBody">
|
|
<description>
|
|
When clearBody is called on a BytesMessage, the body of the message is in
|
|
write-only mode.<br/>
|
|
If clearBody is called on a message in read-only mode, the message body
|
|
is cleared and the message is in write-only mode.
|
|
</description>
|
|
<referenceId>url.message.bytes</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.bytes.method.readBytes(1)">
|
|
<description>
|
|
Refer to javadoc
|
|
</description>
|
|
<reference>
|
|
<url>http://java.sun.com/products/jms/javadoc-102a/javax/jms/BytesMessage.html#readBytes(byte[])</url>
|
|
</reference>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.bytes.method.readBytes(2)">
|
|
<description>
|
|
Refer to javadoc
|
|
</description>
|
|
<reference>
|
|
<url>http://java.sun.com/products/jms/javadoc-102a/javax/jms/BytesMessage.html#readBytes(byte[], int)</url>
|
|
</reference>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.bytes.method.writeObject">
|
|
<description>
|
|
Refer to javadoc
|
|
</description>
|
|
<reference>
|
|
<url>http://java.sun.com/products/jms/javadoc-102a/javax/jms/BytesMessage.html#writeObject()</url>
|
|
</reference>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.map.method.setObject">
|
|
<description>
|
|
Refer to javadoc
|
|
</description>
|
|
<reference>
|
|
<url>http://java.sun.com/products/jms/javadoc-102a/javax/jms/MapMessage.html#setObject()</url>
|
|
</reference>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.map.method.itemExists">
|
|
<description>
|
|
Refer to javadoc
|
|
</description>
|
|
<reference>
|
|
<url>http://java.sun.com/products/jms/javadoc-102a/javax/jms/MapMessage.html#itemExists()</url>
|
|
</reference>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.map.method.getMapNames">
|
|
<description>
|
|
Refer to javadoc
|
|
</description>
|
|
<reference>
|
|
<url>http://java.sun.com/products/jms/javadoc-102a/javax/jms/MapMessage.html#getMapNames()</url>
|
|
</reference>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.stream.method.clearBody">
|
|
<description>
|
|
When clearBody is called on a StreamMessage, the body of the message is
|
|
in write-only mode.<br/>
|
|
If clearBody is called on a message in read-only mode, the message body
|
|
is cleared and the message is in write-only mode.
|
|
</description>
|
|
<referenceId>url.message.stream</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.stream.method.writeObject">
|
|
<description>
|
|
Refer to javadoc
|
|
</description>
|
|
<reference>
|
|
<url>http://java.sun.com/products/jms/javadoc-102a/javax/jms/StreamMessage.html#writeObject()</url>
|
|
</reference>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.stream.method.writeBytes(1)">
|
|
<description>
|
|
Refer to javadoc
|
|
</description>
|
|
<reference>
|
|
<url>http://java.sun.com/products/jms/javadoc-102a/javax/jms/StreamMessage.html#writeBytes(byte[])</url>
|
|
</reference>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.stream.method.writeBytes(2)">
|
|
<description>
|
|
Refer to javadoc
|
|
</description>
|
|
<reference>
|
|
<url>http://java.sun.com/products/jms/javadoc-102a/javax/jms/StreamMessage.html#writeBytes(byte[], int, int)</url>
|
|
</reference>
|
|
</requirement>
|
|
|
|
<requirement requirementId="message.stream.method.readBytes">
|
|
<description>
|
|
Refer to javadoc
|
|
</description>
|
|
<reference>
|
|
<url>http://java.sun.com/products/jms/javadoc-102a/javax/jms/StreamMessage.html#readBytes</url>
|
|
</reference>
|
|
</requirement>
|
|
|
|
<requirement requirementId="properties.group">
|
|
<description>
|
|
JMSXGroupID and JMSXGroupSeq are standard properties clients should use
|
|
if they want to group messages. All providers must support them.
|
|
JMSXGroupID is a string property. JMSXGroupSeq is an int property,
|
|
starting at 1. @todo - need to verify if the range is applicable
|
|
</description>
|
|
<referenceId>section.3.5.9</referenceId>
|
|
<referenceId>table.3-3</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="properties.provider">
|
|
<description>
|
|
JMS reserves the 'JMSX' property name prefix for JMS defined properties.
|
|
Unless noted otherwise, support for these properties is optional. The
|
|
Enumeration ConnectionMetaData.getJMSXPropertyNames() method returns the
|
|
names of the JMSX properties supported by a connection.
|
|
Properties that may only be set by the provider include JMSXUserID,
|
|
JMSXAppID, JMSXDeliveryCount, JMSXProducerTXID, JMSXConsumerTXID,
|
|
JMSXRcvTimestamp and JMSXState.
|
|
</description>
|
|
<referenceId>section.3.5.9</referenceId>
|
|
<referenceId>table.3-3</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="connection.metadata.properties">
|
|
<description>
|
|
ConnectionMetaData provides a list of the JMS defined property names
|
|
supported by the connection. This must include JMSXGroupID and
|
|
JMSXGroupSeq
|
|
</description>
|
|
<referenceId>section.3.5.9</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="subscriber.nolocal">
|
|
<description>
|
|
In some cases, a connection may both publish and subscribe to a topic.
|
|
The subscriber NoLocal attribute allows a subscriber to inhibit the
|
|
delivery of messages published by its own connection.
|
|
</description>
|
|
<referenceId>section.6.11</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="subscriber.durable">
|
|
<description>
|
|
If a client needs to receive all the messages published on a topic,
|
|
including the ones published while the subscriber is inactive, it uses a
|
|
durable TopicSubscriber. JMS retains a record of this durable
|
|
subscription and insures that all messages from the topic's publishers
|
|
are retained until either they are acknowledged by this durable
|
|
subscriber or they have expired.
|
|
</description>
|
|
<referenceId>section.6.11.1</referenceId>
|
|
<referenceId>section.6.3</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="subscriber.durable.clientId">
|
|
<description>
|
|
Sessions with durable subscribers must always provide the same client
|
|
identifier. In addition, each client must specify a name that uniquely
|
|
identifies (within client identifier) each durable subscription it
|
|
creates.
|
|
</description>
|
|
<referenceId>section.6.11.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="subscriber.durable.unique">
|
|
<description>
|
|
Only one session at a time can have a TopicSubscriber for a
|
|
particular durable subscription.
|
|
</description>
|
|
<referenceId>section.6.11.1</referenceId>
|
|
<referenceId>section.4.3.2</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="subscriber.durable.changing">
|
|
<description>
|
|
A client can change an existing durable subscription by creating a
|
|
durable TopicSubscriber with the same name and a new topic and/or
|
|
message selector. Changing a durable subscription is equivalent to
|
|
deleting and recreating it.
|
|
</description>
|
|
<referenceId>section.6.11.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="subscriber.durable.unsubscribe">
|
|
<description>
|
|
TopicSessions provide the unsubscribe method for deleting a durable
|
|
subscription created by their client. This deletes the state being
|
|
maintained on behalf of the subscriber by its provider.
|
|
It is erroneous for a client to delete a durable subscription while it
|
|
has an active TopicSubscriber for it or while a message received by it
|
|
is part of a current transaction or has not been acknowledged in the
|
|
session.
|
|
(Note: this last sentence suggests that a provider doesn't need to check
|
|
that a client can remove a subscription)
|
|
</description>
|
|
<referenceId>section.6.11.1</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="asf.connectionconsumer">
|
|
<description>
|
|
For application servers, connections provide a special facility for
|
|
creating a ConnectionConsumer. The messages it is to consume are
|
|
specified by a destination and a message selector. In addition, a
|
|
ConnectionConsumer must be given a ServerSessionPool to use for
|
|
processing its messages. A maxMessages value is specified to limit the
|
|
number of messages a ConnectionConsumer may load at one time into a
|
|
ServerSession's session.
|
|
</description>
|
|
<referenceId>section.8.2.4</referenceId>
|
|
</requirement>
|
|
|
|
<requirement requirementId="destination.remove">
|
|
<description>
|
|
If a destination is removed via the provider's administration interface,
|
|
and subsequently recreated, all messages to that destination must also
|
|
be removed.
|
|
</description>
|
|
<referenceId>implied</referenceId>
|
|
</requirement>
|
|
|
|
</document>
|