Fixes https://github.com/spring-projects/spring-integration/issues/3705
Closing/destroying `ChannelOutputStream` object does not close the selector therefore it retains redundant pipes/FD that cen be seen using lsof command or ls /proc/
* Close `TcpNioConnection.ChannelOutputStream.selector` in the `ChannelOutputStream`
* Close `TcpNioConnection.ChannelOutputStream` when connection is closed
* Code style clean up
**Cherry-pick to `5.3.x` & `5.4.x`**
# Conflicts:
# spring-integration-ip/src/main/java/org/springframework/integration/ip/tcp/connection/TcpNioConnection.java
Resolves https://github.com/spring-projects/spring-integration/issues/3701
Ensure `TcpSender.removeDeadConnection` is always called, for example when
intercepted and closed via `factory.closeConnectionId` or when closed
connections are harvested from the `connections` map.
**Cherry-pick to 5.4.x, 5.3.x**
Fixes https://github.com/spring-projects/spring-integration/issues/3688
The `WebServiceTemplate` is populated with some defaults from its ctor.
We should rely on the target default template values as much as possible
and don't override them to `null` if end-user doesn't ask about that explicitly
* Fix `BaseWsOutboundGatewaySpec` extensions to populate values to the target gateway
only if they are not null - therefore provided by end-user
* If end-user wants them explicitly `null`, it is better to do that via
externally configured template.
See overloaded variants for DSL: `Ws.marshallingOutboundGateway(WebServiceTemplate)`
and `Ws.simpleOutboundGateway(WebServiceTemplate)`
**Cherry-pick to `5.4.x` & `5.3.x`**
It looks like something has been changed in the transitive dependencies of the plugin:
```
org/eclipse/jgit/storage/file/FileRepositoryBuilder has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0
```
* Downgrade to see and effect without moving to Java 11
Fixes https://github.com/spring-projects/spring-integration/issues/3683
If a transaction is already active while `JdbcLockRegistry` uses
`DefaultLockRepository` to acquire/release a lock, the repository
must execute SQL queries in a separate transaction to prevent
problems with blocking, deadlocking etc.
It also allows to properly follow transaction isolation level that
is set on some methods of `DefaultLockRepository`.
Previously all methods of DefaultLockRepository supported the current
transaction if there are any. Now all methods will always create new
transaction on each call.
* Change tests to be more unit-ish
* Change `@since` for the `DefaultLockRepositoryTests` to `5.3.10`
**Cherry-pick to `5.4.x` & `5.3.x`**
Fixes https://github.com/spring-projects/spring-integration/issues/3675
The `WebSocketInboundChannelAdapter` removes a `SimpMessageHeaderAccessor.NATIVE_HEADERS`
from headers used to create an outbound message.
Turns out not all native headers are mapped by the `StompHeaderAccessor`
to the top-level header entries.
**Cherry-pick to `5.4.x` & `5.3.x`**
The `WebFluxRequestExecutingMessageHandler` does direct `ClientResponse.create(entity.getStatusCode())`
which comes with a `ExchangeStrategies.withDefaults()`.
Even if end-user configures a `WebClient` properly, the response is created with default strategies.
* Rework `WebFluxRequestExecutingMessageHandler` internal logic to call `ResponseSpec.toEntityFlux(BodyExtractor)`
instead of manual `ClientResponse.create()`
* Add unit test to the `WebFluxRequestExecutingMessageHandlerTests` to ensure that configured `maxInMemorySize`
on the `WebClient` strategies has an effect when response body is bigger than expected size
**Cherry-pick to `5.4.x`**
Fixesspring-projects/spring-integration#3652
Do not try to delete non-existing file in `FileExistMode.REPLACE` in the `AbstractRemoteFileOutboundGateway`
**Cherry-pick to `5.4.x` & `5.3.x`**
Resolves https://github.com/spring-projects/spring-integration/issues/3648
When configuring a gateway proxy with XML, but specifying the payload expression
on the method `@Gateway` annotation, the expression was ignored, even though it
had been parsed.
`@Payload` worked.
With this change, if both `@Payload` and `@Gateway` are defined on a gateway method,
`@Gateway.payloadExpression` wins.
* Fix doc links.
# Conflicts:
# src/reference/asciidoc/whats-new.adoc
Fixes https://github.com/spring-projects/spring-integration/issues/3641
When a duplicate cookie name appears in a request, an `IllegalStateException` is thrown.
The default `Collectors.toMap()` does not allow a duplicated keys.
* Handle `servletRequest.getCookies()` as a `MultiValueMap`
* Call `toSingleValueMap()` for the evaluation context variable to restore previous behavior.
The next major version must expose the `MultiValueMap` as is to give access to all cookies from end-user expressions
* Rework some HTTP tests to JUnit 5
**Cherry-pick to `5.4.x` & `5.3.x`**
Resolves https://github.com/spring-projects/spring-integration/issues/3637
If there are no records to receive, the poll blocked for `20*pollTimeout`.
Wake the consumer during partition assignment; however, this changes the behavior
when there are records present - the first poll always returns no records.
Detect that the wakeup was due to assignment and perform another poll.
Also add some debug logging, and don't create a new consumer if the source was
stopped.
**cherry-pick to 5.4.x**
When `DirectChannel` is used for reply producing, the data is
handled on the same thread which has produced it (normally), so
if we have a request-reply afterwards (e.g. `gateway()`), this thread
is blocked waiting for reply.
When the thread is assumed to be non-blocked (e.g. Netty event loop),
the request-reply withing such a thread for the same non-blocking client
causes a deadlock: the thread waits for reply, but at the same time it
supposes to fulfil a synchronization barrier with that reply
* Fix `AbstractMessageProducingHandler.asyncNonReactiveReply()` to use
a `publishOn(Schedulers.boundedElastic())` for reply `Mono` to free
producing thread from potential downstream blocking
* Demonstrate deadlock with a new test in the `RSocketDslTests`;
the original report was against WebFlux, but conditions are really
the same: `reactor-netty` is used as a low-level client
**Cherry-pick to `5.4.x`**
Fixes https://github.com/spring-projects/spring-integration/issues/3627
The `destroy()`, and therefore `stop()` could be called from the `MqttConnectionFailedEvent` handling
in the same thread resetting the `client` property to `null`.
* Check for `this.client != null` in the next block of the `connectAndSubscribe()` to avoid NPE
* Check for `isActive()` in the `scheduleReconnect()` to be sure do not reconnect if channel adapter
has been stopped already
**Cherry-pick to `5.4.x`**
Related to: https://stackoverflow.com/questions/68637283/how-to-customize-response-in-spring-integration-using-webflux-when-a-specific-er
The function provided for the `ConsumerEndpointSpec.customizeMonoReply()` may convert
incoming value to something else.
With wildcards it cannot be compiled without casting.
* Add `<T, V>` generic arg for the `customizeMonoReply()` to conform in and out types carrying.
* Modify `WebFluxDslTests` to demonstrate the problem and confirm the fix
**Cherry-pick to `5.4.x` & `5.3.x`**
Fixes https://github.com/spring-projects/spring-integration/issues/3610
This fix changes the WebFluxRequestExecutingMessageHandler
The change specifically changes the contruction of the
WebClientResponseException to use the `create` factory method.
* Added changes and unit test to cover updated code
Updated code to use simplified exception construction that is more tolerant
of larger payloads.
Updated unit tests to check for specific exception types.
* Corrected checkstyle errors
Corrected checkstyle error in imports.
Corrected whitespace between casts.
Corrected trailing whitespace.
* Added @author
**Cherry-pick to `5.4.x` & `5.3.x`**
If application is connected to a Domino mail server via IMAP, it can happen from time to time that a message is expunged.
This leads to a `MessageRemovedException` when calling `IMAPMessage#getSubject`.
And although debug is set to false this again leads to a `MessageException` and the whole integration flow stops.
* Check for `isExpunged()` before logging a filtered message
* Add `@author`
* Fix debug message for expunged to reflect reality
* Clean up new unit tests a bit
**Cherry-pick to `5.4.x`**
Resolves https://github.com/spring-projects/spring-integration/issues/3600
Previously, the `KafkaProducerMessageHandler` did not synchronize a transaction
with some other transaction (e.g. JDBC); it published in a local transaction instead.
Also configure the Gradle Kotlin Daemon to work with JDK 16.
**cherry-pick to 5.4.x**
Related to https://build.spring.io/browse/INT-MAIN-84/
The `lock.unlock()` must be called in the `finally` block of the
nested `try..catch`, not in the outer which may just fail on `lock.lockInterruptibly()`
in which case there is just not going to be anything we can `unlock()` in the end
**Cherry-pick to `5.4.x` & `5.3.x`**
* Add `org.springframework.integration.history` to trusted default packaged of the `JacksonJsonUtils`
* Add `@JsonCreator` to `MessageHistory` `private` ctor to let it to be created automatically by Jackson
* Add `equals()` and `hashCode()` into `MessageHistory` for the proper `Message` comparison
* Add `MessageHistory` into headers for testing with Redis JSON (de)serialization
**Cherry-pick to `5.4.x` & `5.3.x`**
The `spring.integration.properties` can come with the `noAutoStartup`
property where we can specify a source polling channel adapter endpoint to
not start automatically.
Turns out the `SourcePollingChannelAdapterFactoryBean` propagates its
`autoStartup` property unconditionally which will skip the `noAutoStartup` value
because an `AbstractEndpoint.setAutoStartup()` sets an `autoStartupSetExplicitly` state
* Fix `SourcePollingChannelAdapterFactoryBean` to rely on a `Boolean` object state
and don't call target endpoint `setAutoStartup()` if it was not set
* Adjust `spring.integration.properties` in tests to use `noAutoStartup`
for some `SourcePollingChannelAdapterFactoryBean`
* Verify that property was applied in the `IntegrationFlowTests.testWithSupplierMessageSourceImpliedPoller()`
**Cherry-pick to `5.4.x` & `5.3.x`**
The `@Indexed` comes without any attributes, but it is included
into a chain via `importingClassMetadata.getMetaAnnotationTypes(ann)`.
So, skip attributes from meta annotation when it is `null`
**Cherry-pick to `5.4.x` & `5.3.x`**
We fail with `NoClassDefFoundError` when we use `@EnableIntegrationGraphController`
in WebFlux env without Spring MVC.
Another issue that we don't register CORS for WebFlux
* Extract top-level package protected classes for MVC and WebFlux to register CORS
in the appropriate environment according classpath
* Adjust `HttpIntegrationConfigurationInitializer` and `WebFluxIntegrationConfigurationInitializer`
for native compatibility
* Add `@Indexed` for `@MessagingGateway` for indexer support in Spring Boot and Spring Native
**Cherry-pick to `5.4.x` & `5.3.x`**
# Conflicts:
# spring-integration-http/src/main/java/org/springframework/integration/http/config/IntegrationGraphControllerRegistrar.java
Fixesspring-projects/spring-integration#3570
The module file with the Gradle metadata cannot be published on Maven
Central, which causes issues for some people using a repository manager such
as Artifactory. If it doesn't return a 404 HTTP status, the build fails
instead of ignoring the module.
**Cherry-pick to `5.4.x` & `5.3.x`**