* GH-3888: Fix NPE in the `RedisLockRegistry.destroy()`
Fixed https://github.com/spring-projects/spring-integration/issues/3888
When `RedisLockType.SPIN_LOCK` (default), the `RedisLockRegistry.destroy()`
causes an NPE on the `redisMessageListenerContainer` since pub-sub is not used
in a busy-spin mode
* Check for `redisMessageListenerContainer` before calling its `destroy()`
**Cherry-pick to 5.5.x**
* * Reset properties in the `RedisLockRegistry` after `destroy()`
Fixes https://github.com/spring-projects/spring-integration/issues/3875
The class `static` variables and initialization block are performed on first class access.
* Add "fake" `ClassUtils.resolvePrimitiveType(Integer.class)` call to the `IntegrationRegistrar`
to trigger `ClassUtils` initialization with the current Spring `ClassLoader`
**Cherry-pick to `5.5.x`**
Fixes https://github.com/spring-projects/spring-integration/issues/3843
The `MessageHistory.write()` is missing the `ErrorMessage.originalMessage`
on creating a new `ErrorMessage` with message history header
* Reuse an `ErrorMessage.originalMessage` for newly created `ErrorMessage`
after populating the message history header
**Cherry-pick to `5.5.x`**
Fixes https://github.com/spring-projects/spring-integration/issues/3827
The `AbstractRemoteFileOutboundGateway.doGet()` for a `STREAM` option
does not close the `session` in case of error.
This may lead to some leaks or exhausted caches
* Close `session` in the `catch()` of the `AbstractRemoteFileOutboundGateway.doGet()`
* Adjust the `SftpServerOutboundTests` to configure a `CachingSessionFactory`
for the `testStream()` to verify there is no leaks attempting to
`GET STREAM` non-existing remote file twice
**Cherry-pick to `5.5.x`**
The `Future` for `Producer.send()` can be fulfilled before
we return it (`isDone()`), so `KafkaTemplate` short-circuits
with a `KafkaException`.
* Modify `KafkaOutboundAdapterParserTests.testSyncMode()`
to assert against `KafkaException` which may be thrown earlier
then previously expected `KafkaProducerException`
**Cherry-pick to `5.5.x`**
Related to https://stackoverflow.com/questions/72851234/error-in-startup-application-when-using-serviceactivator-in-spring-cloud-stream
The `MessagingAnnotationPostProcessor` register an `endpoint` bean for Messaging Annotation on POJO methods.
The `IntegrationMBeanExporter` post-process such a bean and registers respective MBean.
It does this not in optimal way scanning all the `IntegrationConsumer` beans for requested `MessageHandler`
which may cause a `BeanCurrentlyInCreationException`.
* Rework the logic of the `IntegrationMBeanExporter.postProcessAbstractEndpoint()` to propagate provided endpoint
for the monitor registration to bypass application context scanning for matched name.
* Swap `equals()` for `monitor` since an `extractTarget()` may return `null`
* Some other code clean in the `IntegrationMBeanExporter`
* Change one of the `@ServiceActivator` in the configuration for the `ScatterGatherHandlerIntegrationTests`
to POJO method.
However, this didn't fail for me with original code unlike in the sample application provided in the mentioned SO thread.
**Cherry-pick to `main`**
The `ClassUtils.isKotlinFaction0()` and `ClassUtils.isKotlinFaction1()`
are wrong names.
* Deprecate `ClassUtils.isKotlinFaction0()` and `ClassUtils.isKotlinFaction1()`
in favor of newly introduced `isKotlinFunction0()` and `isKotlinFunction1()`
**Cherry-pick to `main`**
Fixes https://github.com/spring-projects/spring-integration/issues/3826
By default, the `SimplePool` is used with an `Integer.MAX_VALUE` pool size.
There is a performance degradation in the `setPoolSize()` when we try to
decrease the pool size: the `while` for `permits.tryAcquire()` is too long
close to the current `Integer.MAX_VALUE` pool size
* Revise the logic in the `setPoolSize()` to use `Semaphore.reducePermits()`
instead of the loop.
* Change the calculation for a new pool size for the current pool state:
or it is a size of a new request, or iti s equal to the `inUse.size()`.
It will be reduced on subsequent `releaseItem()` calls
* Reduce the number of `available` according a new pool size based on the `inUse`.
So, if `inUse > newPoolSize`, the `available` is cleared.
Otherewise, it is reduced to the number which would give `newPoolSize` together
with the `inUse` size
**Cherry-pick to `5.5.x`**
Currently, the `MongoDbAvailableRule` logs a warning about missed availability
of the MongoDb server and returns from the `Statement.evaluate()` making the
test not ignored but as passed
* Fix the exception handling in the `MongoDbAvailableRule` for the `Statement`
to call `Assume.assumeTrue()` instead of the plain logging to mark the test as
ignored.
This will make a JUnit test report looking correctly and also will let Sonar Cube
to report test coverage as adequate
**Cherry-pick to `5.5.x`**
Fixes: https://github.com/spring-projects/spring-integration/issues/3822
* Apply spring-framework code style on modified class
* Remove unwanted formatting
* Take pull request comments into account
* Code and JavaDocs clean up
* Improve `Mqttv5BackToBackAutomaticReconnectTests` removing non-related code
* Improve `mqtt.adoc` for this new manual reconnection feature
**Cherry-pick to `5.5.x`**
Fixes https://github.com/spring-projects/spring-integration/issues/3805
The Redis Pub-Sub doesn't work in all the environment, therefore there has to
be a choice to use old busy-spin algorithm
* Change to select between spinLock method and pub-sub method
* Make spinLock as a default one to let the `RedisLockRegistry` work everywhere
* Fix javadoc, convention, lazy init
* Fix javadoc, convention
* Code clean up and docs for `RedisLockType` feature
**Cherry-pick to 5.5.x**
Related to https://stackoverflow.com/questions/72305387/spring-integration-delayer-starts-sending-null-message-payloads-when-switched
In some async use-cases (e.g. `DelayHandler`), the context classloader
might be different for the data to be deserialized from message store.
* Fix `JdbcMessageStore` to populate a bean `ClassLoader` into default
`AllowListDeserializingConverter` from the application context.
The provided `Deserializer` must ensure such a `ClassLoader` itself
* Add warning message to the `LambdaMessageProcessor` when converter
returns `null` for the payload it cannot convert to expected type.
Cannot be raised as error since some applications may already rely
on the `null` conversion result in their method arguments
**Cherry-pick to `5.5.x`**
Fixes https://github.com/spring-projects/spring-integration/issues/3816
The `MappingMongoConverter` now used different path when it
iterates documents form conversion from a DB cursor
* Fix `MongoDbMessageStore.MessageReadingMongoConverter` to override
a `read(TypeInformation<S>, Bson)` method to convert a `MessageWrapper` properly
* Upgrade to the latest MongoDb driver
The `FluxAggregatorMessageHandlerTests.testWindowTimespan()`
relies on the time-based window function of `100` millis.
Looks like a delay of `Thread.sleep(20)` may cause a resources race
condition and window is released only with one item.
* Disable `testWindowTimespan()` since there is no guarantee with what
timing settings it is going to work stably
**Cherry-pick to `5.5.x`**
The Testcontainers rely on the `TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX` ENV var
and build proper image name automatically.
* Deprecate `TestUtils.dockerRegistryFromEnv()` and remove its usage in the project
The `withReuse(true)` and `testcontainers.reuse.enable=true` don't work together with `@Container`.
The JUnit extension gathers those containers and stop them in the end of test class unconditionally.
* Remove `@Container` annotation usage
* Use `@BeforeAll` and `GenericContainer.start()` manually
This way the container ensures to reuse existing running container and don't start a fresh one.
Since the container instance is stored in a `static` property, it is really started only once.
The rest tests in a suite just reuse that existing container.
Ryuk container will take care about their stopping and removal eventually afte JVM exit.
**Cherry-pick to `5.5.x`**
# Conflicts:
# spring-integration-jdbc/src/test/java/org/springframework/integration/jdbc/mysql/MySqlContainerTest.java
Fixes https://github.com/spring-projects/spring-integration/issues/3794
* Replace hard reference to message group with its `id` in the
`AbstractCorrelatingMessageHandler.removeEmptyGroupAfterTimeout()`
* Replace hard reference to message with its `id` in the
`DelayHandler.rescheduleAt()`
**Cherry-pick to `5.5.x`**
* GH-3785: Close stream for persistent collection
Fixes https://github.com/spring-projects/spring-integration/issues/3785
* Fix `CollectionArgumentResolver` and `PayloadsArgumentResolver` to
close the `Stream` of message after its usage
* Rework `AbstractKeyValueMessageStore.removeMessagesFromGroup()`
to iterate input collection of messages not its stream to avoid
the mentioned problem
**Cherry-pick to `5.5.x`**
* * Add `JdbcMessageStoreTests.testMessageGroupStreamNoConnectionPoolLeak()`
to ensure that no leaks in the connection pool anymore.
* Improve `MessageGroupStore.streamMessagesForGroup()` JavaDocs about
requirements to close the `Stream` from persistent message store impls
Fixes https://github.com/spring-projects/spring-integration/issues/3765
The `DefaultMethodInvokingMethodInterceptor` has several strategies
for `default` method invocations in the messaging gateway.
One of them is based on the `Lookup` constructor which causes
a `WARNING: An illegal reflective access operation has occurred`.
This can be done lazily when there is no `MethodHandles.privateLookupIn`
in Java version used for the project.
* Fix `OPEN` enum value for the `Constructor<Lookup>` to be resolved in
a lazy manner via `Supplier` and `boolean` flag
**Cherry-pick to `5.5.x`**