The current `Flux.take()` doesn't allow an arg `< 0` treating
it as an unbound request.
* Change `take()` to `limitRequest()` according strict `MessageSource.receive()`
producing expectations
* Treat `maxMessagesPerPoll < 0` as a `Long.MAX_VALUE` for unbound requests;
`0` is treated in the `limitRequest()` as "no more requests - cancel"
* Revise `AbstractPollingEndpoint` for `LogAccessor` usage
* Add `AbstractPollingEndpoint` class JavaDocs
* Fix tests according `AbstractPollingEndpoint` changes
**Cherry-pick to `5.4.x`**
* Expose `error.ignoreFailures` global property
The global default `errorChannel` can have more then only one logging subscriber.
There is no guarantee in which order subscribers are called and one of them fails
the rest are not called.
* Expose `spring.integration.channels.error.ignoreFailures` global property for
default `errorChannel` and make it `true` by default for better end-user experience
when it is expected to have error being handled by all the subscribers
* * Fix language in the `whats-new.adoc`
* * Fix `JmsTests` for error channel to propagate an exception
* More language fixes for whats-new.adoc
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/3473
When `AbstractEndpoint.start()` and `AbstractEndpoint.isRunning()`
are called from different thread on `synchronized` methods,
we may end up with a dead lock: one thread waits for monitor on
`synchronized` and another waits for the `lifecycleLock`
* Change `AbstractEndpoint.isRunning()` to a plain `return this.running;`
- there is no reason in a lock around returning this `volatile` property state
**Cherry-pick to 5.4.x & 5.3.x**
Fixes https://github.com/spring-projects/spring-integration/issues/3474
The `AbstractTransformer` implementation just wraps a thrown exception into
a `MessageTransformationException`.
It is expected with any method transformer impl (POJO, Lambda direct etc.)
the exception is thrown as is without extra wrapping into an `IllegalStateException`
for consistency
* Fix `LambdaMessageProcessor` to rethrow `RuntimeException` as is
and only wrap into an `IllegalStateException` for all other exceptions
* Fix tests for missed extra stack trace
* Copy request headers when reply is not a Message
Related to https://stackoverflow.com/questions/65887787/spring-integration-unexpected-behavior-on-error-handling-in-splitter-aggregator
Typically `AbstractMessageProducingHandler` implementation with the `shouldCopyRequestHeaders = false`
returns a `Message`(or `MessageBuilder`) as a reply, but when some request handler `Advice` is involved,
we may produce a plain payload and the reply message does not have request headers
* Improve `AbstractMessageProducingHandler` logic to copy request headers into a reply message builder,
when the original reply is not a `Message` or `MessageBuilder`.
This way we improve end-user experience and set them free from copying those headers manually
* Justify a new behavior with the `TransformerTests.testFailedTransformWithRequestHeadersCopy()`
* * Fix Checkstyle violations
Resolves https://github.com/spring-projects/spring-integration/issues/3470
In order to catch issues like this at compile time, we need to set
the `bootClasspath` to ensure API compatibility but this would need some
consistent way to point the JDK 8 libs on all platforms (CI, GitHub Workflows,
dev machines, etc).
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