Commit Graph

96 Commits

Author SHA1 Message Date
Rossen Stoyanchev b8809daf5f Refactor HandlerMethod support in spring-messaging
Introduce base class AbstractMethodMessageHandler for
HandlerMethod-based message handling.

Add MessageCondition interface for mapping conditions to messages
with support for combining type- and method-level annotation
conditions, the ability to match conditions to messages, and also
comparing matches to select the best match.

Issue: SPR-11024
2013-10-24 21:50:49 -04:00
Rossen Stoyanchev 4892a27016 Add STOMP broker relay unit tests 2013-10-23 16:26:28 -04:00
Rossen Stoyanchev bfa6645c7d Make changes for timing related test failures 2013-10-23 13:24:25 -04:00
Rossen Stoyanchev 2d78a066fb Add ListenableFuture to TcpOperations connect methods 2013-10-23 11:55:43 -04:00
Rossen Stoyanchev f3ca3c108c Switch to reactor snapshots and make use of API change 2013-10-22 22:34:41 -04:00
Rossen Stoyanchev 8917821e95 Polish GenericMessage 2013-10-21 16:29:01 -04:00
Rossen Stoyanchev 92a48b72d7 Polish (minor) 2013-10-21 16:26:07 -04:00
Phillip Webb 59fcf5014f Increase timeout for Stomp integration tests 2013-10-18 16:19:33 -07:00
Rossen Stoyanchev d2eff4ead6 Improve GenericMessage.toString()
Restore pringing the payload first and headers second as it has been in
SI but also handle specifically the case where the body is a byte array
to minimize unnecessary "noise" that causes otherwise for STOMP msgs.
2013-10-18 15:28:59 -04:00
Rossen Stoyanchev 61d13547e1 Remove @UnsubscribeEvent
The STOMP UNSUBSCRIBE message does not have a destination header so
there is no obvious simple way to do a mapping and the need for it
is not clear yet.
2013-10-18 15:15:24 -04:00
Rossen Stoyanchev 715a11ce8c Polish AnnotationMethodMessageHandler and annotations 2013-10-18 15:10:34 -04:00
Brian Clozel fb586da673 Support @PathVariable in annotated message handling methods
Prior to this commit, @SubscribeEvent @UnsubscribeEvent and
@MessageMapping annotated message handling methods
could only match a strict message destination.

This commit adds a @PathVariable annotation and
updates the message matching/handling process, since
message handling methods can now match PathMatcher-like
destinations and get path variables injected in parameters.

Issue: SPR-10949
2013-10-18 15:10:34 -04:00
Rossen Stoyanchev be4e5d2841 Add SimpleMessageConverter 2013-10-18 11:33:59 -04:00
Rossen Stoyanchev a53233b351 Fix issue in AbstractMessagingTemplate 2013-10-17 22:23:03 -04:00
Rossen Stoyanchev 29934d7c02 Add TCP abstractions to spring-messaging
This change adds abstractions for opening and managing TCP connections
primarily for use with the STOMP broker support. As one immediate
benefit the change makes the  StompBrokerRelayMessageHandler more
easy to test.
2013-10-17 22:16:15 -04:00
Rossen Stoyanchev a172b32d4c Refactor STOMP relay session
This change consolidates TCP-related logic in the StompRelaySession. As
a result the sub-class SystemStompRelaySession now contains only logic
intrinsic to the shared system session.
2013-10-17 22:16:14 -04:00
Rossen Stoyanchev 17aea892f0 Fix issue with forwarding messaging to STOMP broker 2013-10-17 22:16:14 -04:00
Rossen Stoyanchev 4e3390ae04 Upgrade to reactor 1.0 RC1 and remove MessageChannel
This change upgrades reactor to 1.0 RC1 and also removes the
reactor-based message channel in favor of the one available from
org.projectreactor:reactor-spring.
2013-10-17 22:15:59 -04:00
Juergen Hoeller 187b681b9e Consistency between InvocableHandlerMethod in web and messaging modules 2013-10-16 01:51:48 +02:00
Rossen Stoyanchev bcfbd862c7 Add value() attribute to @Payload 2013-10-14 22:16:13 -04:00
Rossen Stoyanchev 70dfec269b Use alternative UUID strategy in MessageHeaders
This change adds an alternative UUID generation strategy to use by
default in MessageHeaders. Instead of using SecureRandom for each
new UUID, SecureRandom is used only for the initial seed to be
provided java.util.Random. Thereafter the same Random instance is
used instead. This provides improved performance while id's are
still random but less securely so.
2013-10-14 21:55:13 -04:00
Rossen Stoyanchev 57d127b55a Validate if STOMP frame is allowed to have a body
Issue: SPR-10890
2013-10-14 21:37:44 -04:00
Rossen Stoyanchev 7c3749769a Add STOMP broker relay to configure "host" header
Issue: SPR-10955
2013-10-14 21:06:53 -04:00
Juergen Hoeller 3bd6dfe047 Autowiring of generic types
Includes revisions of MethodParameter and DependencyDescriptor (in particular towards a reference to the containing class). Also refines several ResolvableType method signatures.

Issue: SPR-9965
2013-10-15 00:11:23 +02:00
Rossen Stoyanchev 8ae88c20d1 Add support for resolving message headers
This change adds support for @Header and @Headers annotated method
arguments to spring-messaging. Also supported are arguments of type
MessageHeaders, and MessageHeaderAccessor (including sub-types of
MessageHeaderAccessort as long as they provide a wrap(Message<?>)
static factory method).

This change also renames @MessageBody to @Payload.

Issue: SPR-10985
2013-10-13 11:13:16 -04:00
Rossen Stoyanchev 7d3b6497b5 Add support for MIME-based message conversion
The MessageConverter interface in spring-messaging is now explicitly
designed to support conversion of the payload of a Message<?> to and
from serialized form based on MIME type message header.
By default, the MessageHeaders.CONTENT_HEADER header is used but a
custom ContentTypeResolver can be configured to customize that.

Currently available are Jackson 2, String, and byte array converters.
A CompositeMessageConverter can be used to configure several
message converters in various places such as a messaging template.
2013-10-10 17:25:18 -04:00
Rossen Stoyanchev 824cb9f8cd Polish MessageBuilder 2013-10-07 09:27:04 -04:00
Andy Wilkinson 41e411a8a5 Introduce new HEARTBEAT message type
Previously, there was no generic concept of a message that represents
a heartbeat and the STOMP-specific code used a null STOMP command to
represent a heartbeat.

This commit introduces HEARTBEAT as a new SimpMessageType. The STOMP
support has been updated to create HEARTBEAT messages to represent
heartbeats, and to use the new message type as the mechanism by which
heartbeats are identified.
2013-10-02 16:30:53 -04:00
Andy Wilkinson a7f735b50a Make the broker relay heartbeat intervals configurable
Prior to this commit, the intervals at which the broker relay's system
session would send heartbeats to the STOMP broker and expect to
receive heartbeats from the STOMP broker were hard-coded at 10
seconds.

This commit makes the intervals configurable, with 10 seconds being
the default value.
2013-10-02 16:29:43 -04:00
Andy Wilkinson ba11af7f11 Improve broker relay's shutdown and availability events
Previously, when the broker relay was shut down, the TCP client was
closed and the relay sessions were left to find out about the
shutdown as a result of their TCP connections being closed. This led
to problems where an attempt could be made to use a session that was,
in fact, in the process of being shut down.

This commit updates the broker relay to explicitly close each of its
relay sessions as part of its stop processing.
As part of the broker relay being shut down explicitly close each of
its relay sessions. It does so before closing the TCP client so that
the relay sessions know that they are  disconnected before their TCP
connections are closed.

The broker relay's publishing of availability events has also been
improved. Prior to this commit, availability events were published
based on the availability of any relay session. For example, this
meant that a successfully established client relay session would
result in an event being published indicating that the broker's
available even if the system relay session was yet to be established.
This commit updates the relay so that broker availability events are
only published by the system relay session. This allows application
code the use these events as an accurate indication of the
availability of the broker. Clients that are interested in the
broker's availability can find out through the use of heart beats or
through the receipt of an ERROR frame in response to an attempt to
communnicate with the broker.
2013-10-01 21:04:26 -04:00
Rossen Stoyanchev 6ddacdc01d Fix issue in simple broker with peer-to-peer messages
Issue: SPR-10930
2013-09-30 21:02:51 -04:00
Rossen Stoyanchev 48caeef4de Polish and fix issues in STOMP broker relay
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.
2013-09-30 16:37:18 -04:00
Andy Wilkinson 34dd844716 Polishing
- Polish javadoc for CONNECTED_USER_HEADER
 - Improve method ordering
2013-09-30 14:24:57 -04:00
Andy Wilkinson 5025c304b8 Introduce CONNECT_ACK message type
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.
2013-09-30 14:24:57 -04:00
Andy Wilkinson b2f31a3c74 Improve handling of send failures
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.
2013-09-30 14:21:42 -04:00
Rossen Stoyanchev c06ea3b437 Polish logging 2013-09-26 21:27:11 -04:00
Rossen Stoyanchev 469aaa8754 Polish 2013-09-26 16:06:35 -04:00
Andy Wilkinson 6679feb77b Improve handling of missed heartbeats
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.
2013-09-26 16:06:35 -04:00
Andy Wilkinson 496d8321c3 Add heart-beat support to STOMP broker relay
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.
2013-09-26 16:06:35 -04:00
Andy Wilkinson 8d2a376b0f Remove CONNECT-related message buffer from STOMP relay
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.
2013-09-26 16:06:35 -04:00
Andy Wilkinson a489c2cf38 Add StompCodec
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
2013-09-26 16:06:34 -04:00
Rossen Stoyanchev 45eab23e15 Rename @ReplyTo to @SendTo 2013-09-08 21:22:53 -04:00
Sam Brannen 41fa15a484 Polish Javadoc for messaging annotations 2013-09-07 22:07:09 +02:00
Rossen Stoyanchev 62921683fd Introduce ListenableFuture to WebSocketClient
Issue: SPR-10888
2013-09-06 12:28:21 -04:00
Rossen Stoyanchev 71e76196fe Polish StompProtocolHandler 2013-09-05 21:40:15 -04:00
Rossen Stoyanchev 1c47c8f35c Remove TODOs (replaced with JIRA tickets)
Issue: SPR-10703
2013-09-03 23:29:20 -04:00
Juergen Hoeller 8a4c6eb605 Fixed accidental use of Reactor's Assert util
Issue: SPR-10880
2013-09-03 23:56:43 +02:00
Rossen Stoyanchev 30d2f783a7 Modify return type of subProtocolWebSocketHandler bean
The @Bean method now returns WebSocketHandler allowing it to be
decorated via WebSocketHandlerDecorator.
2013-09-03 15:26:47 -04:00
Rossen Stoyanchev 0ac6998e60 Refine destination semantics for msg-handling methods
After this change, annotated message handling methods configured to use
a destination prefix (e.g. "/app") no longer have to include the prefix
in their mapping. For example if a client sends a message to "/app/foo"
the annotated methods should be mapped with @MessageMapping("/foo").
2013-09-03 11:04:00 -04:00
Rossen Stoyanchev e1a46bb57a Add tests to spring-messaging 2013-09-02 20:36:54 -04:00