Fixes https://github.com/spring-projects/spring-integration/issues/3446
* For better resources utilization provide a `Stream<Message<?>>` API
on the `MessageGroupStore`, `MessageGroup` and `MessageGroupQueue`
* Use this API in the `DelayHandler` when it reschedules persisted messages
Fixes https://github.com/spring-projects/spring-integration/issues/3439
The latest Spring Data Redis has introduced an `onErrorResume` function
option for the `StreamReceiver` and this one is now recommended way
to handle errors in the `Flux` from this receiver
* Expose all the `StreamReceiver.StreamReceiverOptionsBuilder` option
onto the `ReactiveRedisStreamMessageProducer`, including `onErrorResume`
* Have a default function as it was before - send into an error channel
supporting (n)ack in the failed message based on the failed record
* Make new setters mutually exclusive with an explicit `StreamReceiver.StreamReceiverOptions`
* Doc polishing
* GH-3437: Add `MessageRecoverer` to AMQP Inbounds
Fixes https://github.com/spring-projects/spring-integration/issues/3437
For better end-user experience with AMQP Inbound Endpoints, expose
a `MessageRecoverer` option
* Test the feature and document this new option
* * Fix Checkstyle & update Copyright
* Fix language in Docs
Co-authored-by: Gary Russell <grussell@vmware.com>
Co-authored-by: Gary Russell <grussell@vmware.com>
* add `Comparable` contract to the initial wrapper so that expressions
containing selection/projection with JsonNode filtering are now possible
* render directly the value of a ValueNode. SpEL parser can now evaluate
correctly the object value when the expression deals with filtering on
`JsonNode` values (<, >, ==...)
* the 2 above changes make this possible:
`property.^[name.getTarget().asText() == 'value1'].name` can now be
written as simply as `property.^[name == 'value1'].name`. The expression
is now fully compatible with other PropertyAccessor types
* rename `ToStringFriendlyJsonNode` to `JsonNodeWrapper` as it reflects
more the capability of the new wrapper
* add a GenericConverter to be able to convert the `JsonNodeWrapper`
class into a `JsonNode` (or its derivative classes) directly while
calling `expression.getValue(..., JsonNode.class)`
* add the possibility to access list items in a json-path like index
=> a negative number will begin from the end of the list <=
* return null value when `JsonNode` cannot handle the property name
(or index)
* Change Json Converter
* Clean up the code style
* Convert JsonPropertyAccessor tests to JUnit 5
* GH-3450: Expose PubSub requireSubscribers option
Fixes https://github.com/spring-projects/spring-integration/issues/3450
* Add `PublishSubscribeChannel` ctors with the `requireSubscribers` option
with a direct delegation to the same option of underlying `BroadcastingDispatcher`
* Add factory methods to the `Channels` & `MessageChannels` to expose
this new `requireSubscribers` option
* Expose an XML `require-subscribers` attribute for the `<publish-subscribe-channel`
* Document this new `requireSubscribers` option
* Introduce a global `spring.integration.channels.error.requireSubscribers` property
for a default `errorChannel`
* Document this property and explain its default `true` in the `error-handling.adoc`
* Remove docs for `spring.integration.postProcessDynamicBeans` since it purpose was
removed since version `5.1` in favor of "always post-process behavior" as it was
always with all the `BeanPostProcessor`s
* * Fix language in docs according review
* * Add more docs about `requireSubscribers` and cross-links between chapters
* GH-3454: From MQTT conversion error - to error ch
Fixes https://github.com/spring-projects/spring-integration/issues/3454
The message converter may return null when we try to covert from the
MQTT message.
The thrown exception may also reset the client connect.
* Fix `MqttPahoMessageDrivenChannelAdapter` to catch any conversion errors
(including `null` result) and try to send an `ErrorMessage` with that info
into the provided `errorChannel`.
Otherwise re-throw it as as
**Cherry-pick to `5.4.x` & `5.3.x`**
* * Apply review language-specific changes
We fail sporadically in some FTP tests against
embedded Mina FTP server.
Turns out there was not enough concurrent logins allowed
on the server instance.
* Change the `ConnectionConfig` for FTP server to allow `1024`
concurrent logins instead of `10` by default
Related to https://build.spring.io/browse/INT-MASTERSPRING40-1314/
When we initialize a `CachingSessionFactory`, we may fail connecting
ot FTP server, but we realize that only when we call `super.getSession()`
from spied factory beans in the test configuration
* Move `super.getSession()` as a first call of the overridden method
and don't change the state of monitored variables when an exception
happens during FTP connection
* GH-3452: Warn Publisher.onError in NullChannel
Fixes https://github.com/spring-projects/spring-integration/issues/3452
The `NullChannel` can subscribe to the `Publisher` payload fully ignoring
the possible data according the `NullChannel` nature.
However an error thrown from the reactive stream processing is also ignored.
* Log WARN message from the `Subscriber.onError()` when `NullChannel`
subscribes to the `Publisher` produced to this channel.
* Mention the logic in the `NullChannel` docs; point to the
`ReactiveRequestHandlerAdvice` for further possible error handling in
the target application
**Cherry-pick to `5.4.x`**
* * Remove unused imports
* * Fix `PseudoTransactionalMessageSourceTests` for `LogAccessor`
from `NullChannel`
To avoid extra `Publisher` subscription work in the target
application "flatten" a returned empty `Flux` for the `void`
expected type into a `Mono.empty()` for automatic subscription
on the output channel
* Subscribe to Publisher in the NullChannel
If a payload of the message in the flow is a `org.reactivestreams.Publisher`,
it must be subscribed somewhere downstream to initiate reactive processing.
The `NullChannel` just ignores the message altogether and therefore `Publisher`
is lost
* Check the payload of the message in the `NullChannel` for `Publisher` type
and subscribe to it
* Verify in the test and mention this logic in the docs
**Cherry-pick to 5.4.x**
* Apply suggestions from code review
Co-authored-by: Gary Russell <grussell@vmware.com>
Co-authored-by: Gary Russell <grussell@vmware.com>
Fixes https://github.com/spring-projects/spring-integration/issues/3445
The `JdbcLockRegistry` improperly unlock the delegate (a `ReentrantLock`)
in the case of `TransientDataAccessException` or a `TransactionTimedOutException` is thrown.
As this occurs in a while loop, the next time the delegate is unlocked,
it not longer as a owner thread and throws an `IllegalMonitorStateException`.
* Move `delegate.unlock()` outside the while loop in the `JdbcLock.unlock()` method
* Add `JdbcLockRegistryDelegateTests` for mocked `LockRepository` to add more coverage
for `JdbcLockRegistry` functionality
**Cherry-pick to 5.4.x, 5.3.x & 5.2.x**
To avoid the `401 from server: Unauthorized`
when we try to reach `https://repo.spring.io/plugins-release`
it is better to point to some more central repository with
no authentication requirements.
Most of the Gradle plugins are managed in the `https://plugins.gradle.org/m2`
repo, not Maven Central
* More GH Actions goodies
* Add RabbitMQ, MongoDB & Redis services into GH actions
* Remove Travis
* * Add `distributionSha256Sum` into `gradle-wrapper.properties`
* Try `TERM: dumb` to see difference for Gradle output in GH action
* Add `-S` to see the reason of test failure
* * Try MQTT plugin for RabbitMQ image
* * Try `-i` for test failure in Gradle on Actions
* * Use `eclipse-mosquitto` image for MQTT on actions
* Fix `FtpServerOutboundTests` for the proper FTP file list
* Output file list for the failed session in the `RotatingServersTests`
* * Adjust SOUT in the test for Checkstyle
* * Make some change to `RotatingServersTests`.
Looks like the order for `@BeforeAll` methods is not determined
and we may start to interaction with FTP server which is not
started yet
* Fix SSL Handshake Test
- we already made this change for the NIO test, but the NET test is failing the same
way - the cert failure switched to the server so the expected exception was not
thrown on the client side. Due to JVM changes.
* * Fix SFTP tests for wrong host and auto-startup state
* Remove `-i` for Gradle in the GH Actions
* * Try `--no-parallel` for Gradle in the GH Actions
* * Try GH actions without Mosquitto
* * Try `cyrilix/rabbitmq-mqtt` for GH Actions
Co-authored-by: Gary Russell <grussell@pivotal.io>
* GH-3438: Add Build from Source into CONTRIBUTING
Fixes https://github.com/spring-projects/spring-integration/issues/3438
It is not clear at the moment what Java version and what build system is used
in the project from the `CONTRIBUTING.adoc`
* Add `Build from Source` section into the `CONTRIBUTING.adoc`
* Point to the `CONTRIBUTING.adoc` from the top level `README.md`
* Fix the current Java version in the `README.md`
* Mention that `Squash commits` must be avoided for subsequent commits into the PR
* * Apply suggest change for docs result
* Change Travis config to use `oraclejdk11` which is minimal already for for the project
* Replace self-closing `<hr/>` with plain `<hr>` in the `overview.html`;
add `lang="en"` to avoid warning
* Use Java 15 API link for JavaDocs
* Use `/current` API link for all the required Spring dependencies
* Fix compatibility with upgraded dependencies
* Move `What's New` for `5.4` to `history`
* Add `XmlUnit` dependency since the latest AssertJ has deprecated its `isXmlEqualTo()`
* Remove `javax.annotation-api` and `apiguardian-api` as redundant dependencies
Fixes https://github.com/spring-projects/spring-integration/issues/3434
Each `RedisLock` has their own `unlinkAvailable` property
therefore we try to `unlink` on every unlock call and also log a WARN
about unavailability of this command in Redis, plus exception
* Move `unlinkAvailable` property to the `RedisLockRegistry` level
to have a check only once on a first `unlock()` call
* Move the whole exception logging onto the DEBUG level, leaving the WARN
only with the `ex.getMessage()`
* Optimize logging the same way in the `RedisMessageStore`
Cherry-pick to `5.3.x & 5.2.x`
Related to https://build.spring.io/browse/INT-MASTER-2240
Turns out the `doOnRequest()` is still not enough to be sure
that subscriber is accepted into the `Publisher`.
Probably because `doOnRequest()` maybe really asked for the
subscription by itself for some logic
* Use `Mono` with `repeatWhenEmpty()` until
`this.sink.currentSubscriberCount() > 0`
Related to https://build.spring.io/browse/INT-MASTERSPRING40-JOB1-1271
* Fix race condition with subscription in the `FluxMessageChannel`:
rely on the `doOnRequest()` to start producing from upstream publishers
* Remove `SourcePollingChannelAdapterTests` since
`Class.getDeclaredConstructor().newInstance()` doesn't rethrow an exception as is
but wrap it into the `InvocationTargetException`.
This is probably the main reason to deprecate a regular `Class.newInstance()`
* Use `LettuceConnectionFactory.setEagerInitialization(true)` in the `RedisAvailableRule`
to avoid possible dead lock with lazy init
* Adjust Redis tests for new `RedisAvailableRule` behavior
Fixes https://github.com/spring-projects/spring-integration/issues/3428
The Kotlin Gradle plugin starting with Kotlin `1.4` adds a standard
Kotlin lib into `compile` scope fully ignoring an `optional` variant.
See more info here: https://kotlinlang.org/docs/reference/using-gradle.html#dependency-on-the-standard-library
* Add `kotlin.stdlib.default.dependency=false` into `gradle.properties`
to rely only on the explicit dependency definitions in the project config
* Remove explicit Kotlin deps from test scope in the target modules since
it is declared globally for all the modules
* Fix author emails in the `publish-maven.gradle` to their VMware variants
* Remove usage of `org.jetbrains.annotations` in favor of `@Nullable`
from Spring Framework
The `IntegrationManagementConfigurer` is a `BeanPostProcessor`
so it must not have direct dependency injection for other beans.
In our case it is a `MetricsCaptor` injected from the
`IntegrationManagementConfiguration`
* Fix `IntegrationManagementConfiguration` and `IntegrationManagementConfigurer`
to rely on the `ObjectProvider<MetricsCaptor>` instead
Tested against latest Spring Boot
**Cherry-pick to `5.3.x` & `5.2.x`**
Fixes https://github.com/spring-projects/spring-integration/issues/3425
It turns out that `IntegrationManagementConfigurer.destroy()` is still too
late to remove `gauges` and Micrometer tries to gather them on application
context close, when many beans are already destroyed
* Catch `ContextClosedEvent` in the `IntegrationManagementConfigurer`
and removed `gauges` from there
* Remove `destroy()` impl since it is out of use already:
the `IntegrationManagementConfigurer` is not supposed to be in the
target application directly, so it looks safe to remove the `DisposableBean`
altogether
**Cherry-pick to `5.3.x` & `5.2.x`**
* Rely on `MProducerSupport.active` for `Flux`
* Fix `MessageProducerSupport` to extract an `active` flag and set it before
`isRunning` - the `Flux` subscription relies on the `takeWhile()`
where in case of `autoStartup = false` we will never start consume because
it is set to `true` already after `doStart()`
* Refactor all the `MessageProducerSupport` implementation with similar
`active` state to use already one from the super class
**Cherry-pick to 5.3.x**
* * Remove `MessageProducerSupport.setActive()`
to not let to mutate it from the implementations
* Set `active` to `false` in the `destroy()`
* Clean up and fix typos in the affected `JmsMessageDrivenEndpoint`
* * Pull `active` flag down to the `AbstractEndpoint`
* Set `active = true` in the `start()` before calling `doStart()`
* Do same for `active = false` in the `stop()`
* Clean up `AbstractEndpoint` impls to not call `doStart/doStop` for nothing
* Refactor endpoints to rely on the `active` state from the `AbstractEndpoint`
not their own
* Add Java DSL for R2DBC module
* Add JavaDocs for R2DBC component setters
* Introduce a `R2dbcMessageSource.SelectCreator` to narrow
a `StatementMapper` API access from SpEL
* Add missed `package-info.java` into R2DBC packages
* Add `hamcrest-core` as test dependency into SI-R2DBC
since Awaitility doesn't work without it
* * Add `@NonNullApi` to R2DBC packages
Fixes https://github.com/spring-projects/spring-integration/issues/3394
* Fix (wrong) copied/pasted text in the Redis Queue Inbound Gateway attribute
descriptions
* Fix some docs typos
* Add `jmx.adoc` into an `index.adoc` and `index-single.adoc`
* Add R2DBC, Redis Stream and ZeroMQ channel adapters into an `endpoint-summary.adoc`