* INT-3494: Resolve dir for writing as a Resource
JIRA: https://jira.spring.io/browse/INT-3494
The expression for local directory can be resolved into a `Resource`
or resource location.
* Fix `ExpressionUtils.expressionToFile()` to support `Resource` and
also use `ResourceUtils.getFile(path)` when expression result is a string
* Modify tests to ensure that resource is resolved properly
* Upgrade affected tests to JUnit 5
* Mention an new functionality in docs
* * Improve Java doc for `ExpressionUtils.expressionToFile()`
* Finish the sentence in the `file.adoc`
Fixes https://github.com/spring-projects/spring-integration/issues/3107
The `MessagingGatewaySupport` has an `errorOnTimeout` option to throw
a `MessageTimeoutException` when downstream reply doesn't come back in
time for configured reply timeout
* Expose an `errorOnTimeout` option as a `TcpInboundGateway` ctor
property
* Add new factory methods into a `Tcp` factory for Java DSL
* Ensure a property works as expected in the `IpIntegrationTests`
* Document a new option
* Add a setter for MessagingGatewaySupport.errorOnTimeout option
* Expose an `errorOnTimeout` option on the DSL's `MessagingGatewaySpec`
making all the out-of-the-box inbound gateways possible to react to the
`MessageTimeoutException` when no reply during reply timeout
* Propagate properly `errorOnTimeout` in the `JmsInboundGateway`
* Modify docs respectively
* Improve docs about `errorOnTimeout`
Related to https://github.com/spring-projects/spring-framework/issues/23812
* Modify `FunctionsTests.kt` test to be sure that fall back to SpEL
invocation in case of Kotlin lambda works as expected.
This is like an additional test to the fix in Spring Framework
* Currently `MessagingMethodInvokerHelper.getTargetClass()` logs a
debug message when it can't cast a `targetObject` into an `Advised`.
Such a message is misleading and really unnecessary noise in the target
applications
* Fix the logic of the method to check `targetObject instanceof Advised`
before trying to extract interfaces from proxy.
This way we don't need to catch any exceptions at all.
If something will fail, it should be bubbled upstream for possible fixes
* Convert `MethodInvokingMessageProcessorTests` to JUnit 5 and restore
a couple tests
Fix a logic in the `JsonToObjectTransformer.obtainResolvableTypeFromHeadersIfAny`
when we have both `JsonHeaders.RESOLVABLE_TYPE` and `JsonHeaders.TYPE_ID`
and `JsonHeaders.RESOLVABLE_TYPE` header is valid `ResolvableType`, so
`JsonHeaders.TYPE_ID` doesn't override its value to return
* GH-3096: Skip RESOLVABLE_TYPE header in mapping
Fixes https://github.com/spring-projects/spring-integration/issues/3096
When we sent an AMQP message we should not map a
`JsonHeaders.RESOLVABLE_TYPE` header which is a `ResolvableType` and
isn not compatible after converting to string
Also improve `JsonToObjectTransformer` to ignore a
`JsonHeaders.RESOLVABLE_TYPE` when it is type of String
* * Fix `obtainResolvableTypeFromHeadersIfAny()` logic
* Use `EmitterProcessor` for Channels adaptation
Related https://github.com/spring-cloud/spring-cloud-stream/issues/1835
To honor a back-pressure after `MessageChannel` adaptation it is better
to use an `EmitterProcessor.create(1)` instead of `Flux.create()`.
This way whenever an emitter buffer is full, we block upstream producer
and don't allow it to produce more messages
**Cherry-pick to 5.1.x**
* * Wrap every new subscription into a `Flux.defer()`
* Fix `ReactiveStreamsConsumerTests` to use a new `Subscription` after
each `stop()/start()` on the `ReactiveStreamsConsumer`
* * Remove unused imports
* Extract `BaseIntegrationFlowDefinition`
Kotlin inline reified functions cannot override as syntax sugar generic
Java methods.
* Extract a `BaseIntegrationFlowDefinition` with strong typed methods,
plus those which doesn't have a syntax sugar variants
* Leave in the `IntegrationFlowDefinition` only those generic methods
which are just a syntax sugar without any types requirements
This way we can write Kotlin inline reified functions as an extension
with the same names to make a Kotlin DSL much cleaner
* * Override methods in the IntegrationFlowDefinition for bytecode compatibility
* Extract `protected` getters and setters for `BaseIntegrationFlowDefinition`
properties to allow a proper extension
* Use those getters and setters in the code
* * Add // NOSONAR for overridden methods
* Ensure that dynamic routes are included into graph
Modify an `IntegrationGraphServerTests` to be sure that dynamic routes
are included into the graph (with links) after sending a message to the
router and rebuilding a graph
* * Fix test for the actual numbers to expect
* GH-3079: Use getMostSpecificMethod for SpEL calls
Fixes https://github.com/spring-projects/spring-integration/issues/3079
It turns out that we need to use a *most specific* method for the target
to be called reflectively from the SpEL
NOTE: We drop a *Method not found* error in case of wrong method source
since now we find a right source via `ClassUtils.getMostSpecificMethod()`
**Cherry-pick to 5.1.x**
* * `@Ignore` `MethodInvokingMessageProcessorTests.testProcessMessageMethodNotFound()`
instead of removal
* Refinement for gateway Mono processing
* Introduce a `MessagingGatewaySupport.MonoReplyChannel` instead of
`FutureReplyChannel` for better on demand handling and reusing a
`Mono` returned from the target handler
* Refactor `GatewayProxyFactoryBean` to identify a target return type
(including generics for `Function`) during initialization
* Handle a `Mono` return type via
`MessagingGatewaySupport.sendAndReceiveMessageReactive()`
* Some `@Nullable` in the `GatewayProxyFactoryBean` and `ExpressionUtils`
* Add `MonoFunction` test-case into the `FunctionsTests.kt`
* * Deprecate `GatewayProxyFactoryBean.setServiceInterface()` in favor of
ctor initialization
* Fix `GatewayProxyFactoryBean.setServiceInterface()` usage in tests
The method reference together with a `IntegrationFlows.frm(Supplier<?>)`
do the trick to avoid a method name resolution and also gives us a code
navigation in the IDE
* Improve `channel.adoc`: polishing, new channels, java config
* Make `LoadBalancingStrategy` in the `DirectChannel` ctor as
`@Nullable` to reflect the real logic behind
* More Dos and polishing according PR comments
* Mention WebFlux and RSocket endpoints in the `endpoint-summary.adoc`
table
* More reactive streams docs
* `SourcePollingChannelAdapter` polishing
* Wrap multi-value publisher into `Mono.just()` in the `AbstractMessageProducingHandler`
instead of emitting just only a first item for the standard reply
Doc polishing
* Hide `toReactivePublisher()` from lambdas
When an `IntegrationFlow` is declared via lambda, it is impossible
to materialize it as a `Publisher` since we lose a Lambda context and
finish with a `NoSuchBeanException` when we would like to inject that
`Publisher`
* Make `IntegrationFlowDefinition.toReactivePublisher()` as `protected`
and expose it on the `IntegrationFlowBuilder` level
* Use `Channels` as a singleton: no reason in overhead for its instances
* Some code style polishing for `IntegrationFlowDefinition`
* Restore `Channels.super()` call
* Fix some typos in `webflux.adoc` and `dsl.adoc`
* Make `FunctionsTests.kt` more Kotlin friendly
* Improve RSocket components and tests for them,
especially rely on the default `RSocketStrategies` in the
target SF RSocket components
* Rework `ServerRSocketConnector.setClientRSocketKeyStrategy` to use the whole `MessageHeaders` for consultation.
It turns out that just destination is not enough since it can be used from different clients
* Make the key based on the provided `setupData` by default
* Include all the `MessageHeaders` into the `RSocketConnectedEvent`
* Improve Docs according review feedback and Docs in SF
Doc polishing
Fixes https://github.com/spring-projects/spring-integration/issues/3052
Starting with version `5.1`, a `LambdaMessageProcessor` is based on the
`MessageConverter` instead of plain `ConversionService`.
(A `ConfigurableCompositeMessageConverter` is used from the application
context.)
However a type conversion based on the `@IntegrationConverter` is lost
in the `GenericMessageConverter` because it doesn't use an
`integrationConversionService` from the application context
* Change `ConfigurableCompositeMessageConverter` to configure a
`GenericMessageConverter` with an `integrationConversionService`
if any
* Fix `MessagingMethodInvokerHelper` to populate a `BeanFactory` into
its internal `ConfigurableCompositeMessageConverter`
* Ensure in the `LambdaMessageProcessorTests` that
`@IntegrationConverter` is applied for ``LambdaMessageProcessor` as well
**Cherry-pick to 5.1.x**
Fixes https://github.com/spring-projects/spring-integration/issues/3047
* Improve `GatewayProxyFactoryBean` to determine the return type of the
method call from the interface generic types, when the `serviceInterface`
is a `java.util.function.Function`
* Propagate `MethodArgsHolder` as a `rootObject` for SpEL evaluations
* Deprecate `#gatewayMethod` and `#args` evaluation context variables
in favor of `MethodArgsHolder` as root object.
They will be removed in the future release and a single
`EvaluationContext` will be used for all the gateway expressions
* Introduce an
`IntegrationFlows.from(Class<?> serviceInterface, Consumer<GatewayProxySpec> endpointConfigurer)`
to allow to configure any valid gateway proxy options similar to what
we have with the `<gateway>` and `@MessagingGateway`.
This way we are very close to consistency between different approaches
* * Remove `default` prefix from `GatewayProxySpec` options
* Document the change
- republish certain events as `ApplicationEvent`s.
* * Add ApacheMinaFtplet to provide the same functionality with FTP
* Fix typo
* * Polishing javadocs and event toString() methods
Fixes https://github.com/spring-projects/spring-integration/issues/3003
Statically defined flows with a publish/subscribe channel invoke the
subscriptions in natural (declared) order.
The components in the flow are started by the application context in
phases (consumers, then producers) and bean declaration order within
each phase.
When a dynamically declared flow is started, the components are started
by the `StandardIntegrationFlow` in reverse order (last to first) so that
we don't start producing messages before the flow is fully wired.
This has the side-effect that pub/sub subscribers are invoked in an
unnatural (last to first) order.
All subscription sub-flows start with a bridge from the pub/sub channel
to the first component's input channel.
The `BroadcastingDispatcher` honors the `Ordered` interface.
Change the `PublishSubscribeSpec` to set the `order` property so that
subscribers are always invoked in the natural order, regardless of whether
the flow is statically or dynamically defined.