Fix error in te code that handles the result of sending a heartbeat
Fix error in processing DISCONNECTED frames that closed the TCP
connection before the message was sent.
Previously, handling of a STOMP CONNECT message and sending of a
CONNECTED response was performed by StompProtocolHandler if it was
backed by SimpleBrokerMessageHandler, or left up to the real message
broker if it was backed by StompBrokerRelayMessageHandler. This
wasn't ideal as it should be StompProtocolHandler's job to simply map
messages to and from the STOMP protocol, not to do part of the
broker's job and respond directly to CONNECT.
This commit introduces a new message type, CONNECT_ACK. When it
receives a CONNECT message, SimpleBrokerMessageHandler will now
respond with a CONNECT_ACK message that StompProtocolHandler can map
into a STOMP CONNECTED message. The CONNECT_ACK message contains the
CONNECT message as a header so that StompProtocolHandler has access to
its accept-version header.
StompProtocolHandler has been simplified so that a CONNECT message
is always passed to the output channel, irrespective of whether it's
backed by a simple broker or a real broker. The handleConnect flag,
and the code that would set it correctly depending on the app's
configuration, has been removed.
Prior to this commit, a failure to send a heartbeat was ignored and a
failure to forward a message to the broker would result in an error
frame being sent but nothing more.
Following this commit, a failure to send a heartbeat to the broker
is treated as a TCP client failure. Furthermore, if the system relay
session fails to forward a message to the broker an exception is
thrown. Typically, the system relay session will be forwarding
messages on behalf of local application code, rather than a remote
WebSocket client. Throwing an exception allows the application code
to be notified of the problem directly, rather than via a broker
availability event.
Renamed ResourceUrlMapper to ResourceUrlGenerator and refactored it
to be configured with Resource-serving HandlerMappings as opposed to
having them detected in the ApplicationContext through the
BeanPostProcessor contact.
Renamed and polished ResourceUrlEncodingFilter to ResourceUrlFilter
and added tests.
This change splits out resource transformation out from the
ResourceResolverChain so that chain is focused entirely on resource
resolution (as its name suggests). The invocation of transformers
is left as a separate step, it uses a different (recursive)
algorithm in any case and iterates over a different set of objects.
Also ResourceResolverChain is now limited strictly to methods that
a ResourceResolver should be able to use to delegate to remaining
resolvers.
Furthermore, ResourceResolverChain now maintains an internal index
of the "current" resolver so that resolvers don't have to pass the
chain when invoking it much like a (Servlet API) FilterChain works.
If the last resolver calls the chain again, a null value is returned.
Commit 2397b21096 changed websocket
support to use GlassFish 4.0.1 nightlies, but broke support for 4.0. In
GlassFish 4.0.1, the package that TyrusEndpoint is located in changed.
This commit provides an abstract handler that does all required
GlassFish setup, but delegates to version specific upgrade handlers to
create the final TyrusEndpoint.
GlassFish 4.0 handler uses reflection to create its endpoint to prevent
dependency issues of depending on different versions of
tyrus-websocket-core and tyrus-container-servlet
Previously, when a broker heartbeat was mnissed, the STOMP connection
would be left in a semi-disconnected state such that, for example, the
read and write idle callbacks would still be active, even though
the underlying TCP connection had been nulled out.
As part of disconnecting the STOMP connection, this commit closes the
underlying TCP connection when a heartbeat's missed which cancels the
read and write idle callbacks. It also now copes with the underlying
TCP connection being null when sending a heartbeat to the broker. This
protects again a race condition between the write idle callback being
fired, such that a heartbeat needs to be sent, and the connection
being nulled out due to it being closed.
Previously, the STOMP broker relay did not support heart-beats. It sent
0,0 in the heart-beats header for its own CONNECTED message, and set the
heart-beats header to 0,0 when it was forwarding a CONNECTED from from a
client to the broker.
The broker relay now supports heart-beats for the system relay session.
It will send heart-beats at the send interval that's been negotiated
with the broker and will also expect to receive heart-beats at the
receive interval that's been negotiated with the broker. The receive
interval is multiplied by a factor of three to satisfy the STOMP spec's
suggestion of lenience and ActiveMQ 5.8.0's heart-beat behaviour (see
AMQ-4710).
The broker relay also supports heart-beats between clients and the
broker. For any given client's relay session, any heart-beats received
from the client are forwarded on to the broker and any heart-beats
received from the broker are sent back to the client.
Internally, a heart-beat is represented as a Message with a byte array
payload containing the single byte of new line ('\n') character and
'empty' headers. SubscriptionMethodReturnValueHandler has been updated
to default the message type to SimpMessageType.MESSAGE. This eases
the distinction between a heartbeat and a message that's been created
from a return value from application code.
Before this change, the StompProtocolHandler always responded to
clients with a CONNECTED frame, while the STOMP broker relay
independantly forwarded the client CONNECT to the broker and waited
for the CONNECTED frame back. That meant the relay had to buffer
client messages until it received the CONNECTED response from
the message broker.
This change ensures that clients wait for a CONNECTED frame from
the message broker. The broker relay forwards the CONNECT frame to
the broker. The broker responds with a CONNECTED frame, which the
relay then forwards to the client. As a result, a (well-written)
client will not send any messages to the relay until the connection
to the broker is fully established.
The StompProtcolHandler can now be configured whether to send CONNECTED
frame back. By default that is off. So when using the simple broker,
the StompProtocolHandler can still respond with CONNECTED frames.
The relay's handling of a connection being dropped has also been
improved. When a connection for a client relay session is dropped
an ERROR frame will be sent back to the client. If a connection is
closed as part of a DISCONNECT frame being sent, no ERROR frame
is sent back to the client. When the connection for the system relay
session is dropped, an event is published indicating that the broker
is unavailable. Reactor's TcpClient will then attempt to re-restablish
the connection.
Previously, the broker relay's TCP client used Reactor's built in
delimited codec as part of its parsing of STOMP frames. \0 was used as
the delimiter. This worked for most STOMP frames but, crucially,
not for frames with a body that contained \0: when such a frame was
received it would be truncated.
This commit adds a custom codec that parses STOMP frames more
intelligently. It honours the content-length header allowing it to
correctly parse frames with a body that contains \0. The codec largely
delegates to two new classes: StompEncoder and StompDecoder. For
consistency, code that previously used StompMessageConverter has been
reworked to use these new encoder and decoder classes.
Issue: SPR-10818
This fine-tuned change restores the original Spring 3.0 behavior for Oracle AQ, and also allows for other ConnectionFactory types to comply with the "getDataSource()" pattern.
Issue: SPR-10829
Prior to this commit, the DispatcherServlet would send an error
response using the HttpServlet API when no Handler was found to
handle this request.
Now the DispatcherServlet can be configured to throw a
NoHandlerFoundException, when the throwExceptionIfNoHandlerFound
property is set to "true".
Those exceptions can be later on caught by default or custom
HandlerExceptionResolvers/ExceptionHandlers.
Issue: SPR-10481
Prior to this commit, RestTemplate would not would
not accept IPv6 raw addresses in URLs because UriComponentsBuilder
would not parse/encode the Host part correctly.
The UriComponentsBuilder now parses and encode raw IPv6 addresses
in the "[1abc:2abc:3abc::5ABC:6abc]" format and also supports the
use of IPv6 scope_ids (see JDK8 java.net.Inet6Address),
like "[1abc:2abc:3abc::5ABC:6abc%eth0]".
Issue: SPR-10539
S0 doesn't seem to be universally used for SQL grammar problems: see MS SQL Server's RAISERROR. This was reported years back; not sure why the fix didn't actually appear in the codebase back then.
Issue: SPR-10902
Update CallMetaDataContext to use the metaDataProvider
createDefaultOutParameter method when creating a SqlOutParameter as
a result of a SQL function call.
This change allows Spring to support Oracle cursor types when returned
from functions.
Issue: SPR-10606
Update `CacheAspectSupport` to expand any var-arg parameters before
calling `KeyGenerator` implementations. Prior to this commit var-args
would be passed to `KeyGenerator` implementations as a nested array,
often causing the same key to be generated regardless of the arguments.
Issue: SPR-10870