Fixes https://github.com/spring-projects/spring-integration/issues/2987
To resolve XSD files properly from the classpath, their HTTPS reference
must be present in the `spring.schemas` to avoid the Internet interaction
for resolving an XSD file
**Cherry-pick to 5.1.x, 5.0.x & 4.3.x**
* After introduction an `rsocketFrameType` header in the message,
we don't need a custom `IntegrationRSocket` any more.
Fully rely on the `MessagingRSocket` from the Spring Messaging, only
handle properly a `RSocketFrameTypeMessageCondition.CONNECT_CONDITION`
for connections from clients to emit an `RSocketConnectedEvent`
* Copy a `ChannelSendOperator` from the Spring Messaging for the proper
reply handling, when we are interested in the source `Publisher`
subscription first.
See its JavaDocs for more info
* Reusing already `public PayloadUtils` instead of its method copies
For the `connect` frame Spring Messaging RSocket support has introduced
an new `@ConnectMapping` annotation.
* Use `@ConnectMapping` in the test controller's method to properly
map to the connection from the client
* Add support for the `MetadataExtractor` in the
`AbstractRSocketConnector`, `IntegrationRSocketMessageHandler`
and `IntegrationRSocket` for more flexible RSocket metadata
* Use `DefaultMetadataExtractor` in the
`IntegrationRSocketMessageHandler.afterPropertiesSet()` since the getter
is not available on the super class yet
* Use a `MetadataExtractor` in the `IntegrationRSocket` instead of an
old `CompositeMetadata` manipulation
* Use `PayloadUtils.retainDataAndReleasePayload()` since it is `public`
already
* Downgrade to the `rsocketVersion = '0.12.2-RC4'` since it looks like
the latest `1.0.0-RC1-SNAPSHOT` doesn't parse a frame properly on the
server side
When RSocket client connects to the server there is no reason to wrap
a `ConnectionSetupPayload` into a `Message` since we are not going to
send it downstream
* Refactor `IntegrationRSocket.handleConnectionSetupPayload()` just
return a `Mono<DataBuffer>` for converted `ConnectionSetupPayload`
* Ask for a `destination` and `RSocketRequester` from the
`IntegrationRSocket` instead of message headers
Looks like there is some connection race condition in Netty on Linux,
so we may not be started on server side fully when we try to select a
port from the OS
* Move local port resolution and, therefore, RSocket server start into
the earlier phase before creating a client
The `http://example.org` is not white-listed in `nohttp` and it
doesn't resolve SSL handshake on HTTPS schema
* Add `@Deprecated` into `SimpleMessageListenerContainerSpec.txSize()`
* It looks like we don't need to manage Reactor dependencies in the
RSocket module: the `io.rsocket:rsocket-transport-netty` brings
everything we need, although it doesn't that with its own supported
versions
* Use non-HTTPS url for `example.org` in test config to avoid SSL
handshake
* Add `RSocketInboundGateway`; refactoring
* Extract an `AbstractRSocketConnector` for common client and server connectors logic
* Introduce an `IntegrationRSocketAcceptor` and `IntegrationRSocket` for the
mapping and handling logic of RSockets and messages in between
* Introduce an `IntegrationRSocketEndpoint` marker interface for Inbound Gateway mappings
* Add `RSocketInboundGateway` implementation, which is called from the
`IntegrationRSocketAcceptor` by the `IntegrationRSocketEndpoint` mapping
* Add `RSocketConnectedEvent` to emit when the client is connected to the server.
It does not make sense in Spring Integration to delegate such a logic into the
`RSocketInboundGateway`
* * Add `ServerRSocketConnector` to represent an RSocket server and
container for connected `RSocketRequester`s from clients
* Extract `accept(ConnectionSetupPayload setupPayload, RSocket sendingRSocket)`
server logic into an internal `ServerRSocketAcceptor` extension for the
`IntegrationRSocketAcceptor`
* Address PR comments:
- `RSocketConnectedEvent.toString()`
- `ApplicationEventPublisherAware` into the `ServerRSocketConnector`
- Log RSocket connection if no `this.applicationEventPublisher`
* Remove `handleConnectionSetupPayload()` from the `IntegrationRSocket`
since it is not delegated to the target handler
* Provide reasonable default `RSocketStrategies` for the
`AbstractRSocketConnector` and `RSocketInboundGateway`
* Add initial `RSocketInboundGatewayIntegrationTests`
* * Don't use `BytyBuffer` in the `RSocketConnectedEvent.toString()`
* Always `payload.retain()` when we convert `Payload` to `DataBuffer`
* Fix `IntegrationRSocketAcceptor.detectEndpoints()` stream logic
to really iterate over all the `IntegrationRSocketEndpoint` beans
* Fix test to use an explicit `ClientConfig` class for the
`@SpringJUnitConfig`: looks like JUnit 5 is OK to scan for `package
protected` classes as well
* Add request/reply tests into the `RSocketInboundGatewayIntegrationTests`
for both server and client sides
* * Remove `DataBuffer` from `RSocketConnectedEvent.toString()`
* * Fix Checkstyle violation in the RSocketInboundGatewayIntegrationTests
* Use properly `cache()` for the `Mono` in the `ClientRSocketConnector`
* Don't require a `publisherElementTypeExpression` in the
`RSocketOutboundGateway`: the target element type is determined
automatically in the `DefaultRequestSpec.toResponseSpec()`
* SF has deprecated `MediaType.APPLICATION_JSON_UTF8`: fix all its usage
in favor of recommendations to use the `MediaType.APPLICATION_JSON` instead
* Also fix plain `application/json;charset=UTF-8` literals to use
`MediaType.APPLICATION_JSON` instead
* Introduce a `ClientRSocketConnector` to represent a common logic for
client side connection and management an obtained `RSocket`
* Rework the `RSocketOutboundGateway` to perform similar RSocket request
logic on the server side as well.
* Refactor `RSocketOutboundGatewayIntegrationTests` to demonstrate that
RSocket requests work the same way from the server side as well.
For this reason a `CommonConfig` has been extracted with the same
`RSocketOutboundGateway` configuration reuse on both server and client
sides.
* Add initial support for RSockets
* Add `spring-integration-rsocket` module and respective dependencies
* Implement `RSocketOutboundGateway` based on the Spring Messaging
`RSocketRequester`.
This component supports dynamic RSocket properties via expressions
against request message.
to handle `Publisher` for requests, it must be present in the request
message `payload` instead of `FluxMessageChannel` upstream, since the
last one just flattens events to be handled in the `MessageHandler` one
by one.
The result `Mono` is subscribed downstream in the `FluxMessageChannel`
or directly by the `AbstractReplyProducingMessageHandler`.
If result is a `Flux` it is just wrapped into the `Mono` to be processed
downstream by end-user code.
The point is that these request/replies are volatile and live in the
particular context meanwhile a `FluxMessageChannel` is long living
publisher in the application context boundaries.
* The `RSocketOutboundGatewayIntegrationTests` is an adapted copy of
`RSocketClientToServerIntegrationTests` from Spring Messaging
* Add `doOnError()` into the `Flux` created in the
`AbstractMessageProducingHandler` for `Publisher` replies
* * Use singular for the `RSocket` term
* Use no-op `Consumer` for the `strategiesConfigurer` and
`factoryConfigurer` in the `RSocketOutboundGateway` and also
`Assert.notNull()` in the appropriate setters to avoid null check during
`RSocketRequester.builder()` initialization
* Use `TcpServer.create().port(0)` in the
`RSocketOutboundGatewayIntegrationTests` to allow to select free OS port
and bind into it.
The selected port is used later for client configuration in the
`RSocketOutboundGateway` bean definition
* * Change `RSocketOutboundGatewayIntegrationTests.PORT` to lower case