Since the classes load their imports explicitly we can't use them for
classes which provides utilities to check classpath
* Move imports to fully qualified names in the target utility method
**Cherry-pick to 4.3.x**
Move `JacksonJsonUtils.isPresent` methods to separate `JacksonPresent` class
Polishing
* Rename `ReactiveConsumer` to `ReactiveStreamsConsumer`
* Rename `FluxSubscribableChannel` to `ReactiveStreamsSubscribableChannel`
* Remove the `processor` functionality from the `FluxMessageChannel`
in favor of internal `FluxSink` as it is recommended by the Project Reactor:
> Most of the time, you should try to avoid using a Processor.
They are harder to use correctly and prone to some corner cases.
* Make connectable, upstream publishers for the `FluxMessageChannel` as
bridges to the internal `sink` via `this::send`.
This way we are able to receive data from multi sources.
When the source is completed (e.g. `Mono` in case of WebFlux response),
the downstream flow isn't completed.
* Rework `MessageChannelReactiveUtils#PollableChannelPublisherAdapter`
to be based on the `Flux.create()` and `onRequest()` to poll channel for messages
* Add one more request to the `ReactiveHttpRequestExecutingMessageHandler`
to be sure that we consume different `Mono`s by the `FluxSubscribableChannel`
properly without completion
* Upgrade to the `spring-io-plugin:0.0.7.RELEASE`
Add `IntegrationConsumer` implementation to the `ReactiveStreamsConsumer`
JIRA: https://jira.spring.io/browse/INT-4267Fixes: spring-projects/spring-integration#2110
The documentation clearly point that we can simply use JSON (de)serialization
with the `RedisMessageStore`, but actually it isn't so easy
* Fix `MessageGroupMetadata`, `MessageHolder`, `MessageMetadata` for Jackson
deserialization compatibility
* Add `MessageHeaders`-based ctor to the `AdviceMessage`
* Add `MessageHeadersJacksonSerializer` to serialize `MessageHeaders`
to the `HashMap` for easier deserialization afterwards
* Add deserializer implementations for all `Message` types
* Add convenient `JsonObjectMapperProvider#jacksonMessageAwareMapper()`
factory method to build `ObjectMapper` supplied with mentioned above
(de)serializers
**Cherry-pick to 4.3.10 without `MessageHolder` and `MessageMetadata`**
Address PR comments and document the feature
Doc Polishing
https://build.spring.io/browse/INT-MASTER-653
The test-case uses only 1 second to wait for the message
in the `QueueChannel`.
That isn't enough on slow environment like CI causing failure for
the current test and unexpected value in the queue for the subsequent
tests
* Fix timeouts
* Get rid of `CountDownLatch` - the same is done by the wait on queues
* Purge queue in between tests.
This way we may not have failed subsequent test, thus failure analyze
will be much easier
* Rework `testRollback()` to wait for good result after one retry over
rollback
* Remove duplicate bean definition from XML config
**Cherry-pick to 4.3.x and 4.2.x**
JIRA: https://jira.spring.io/browse/INT-4258
Since Redis `ZADD` command doesn't perform incrementation by default,
it should be consistent in the `RedisStoreWritingMessageHandler` as well
* Make a default behavior of the `RedisStoreWritingMessageHandler`
regarding `INCR` option as `false`
* Provide some performance refactoring for the
`RedisStoreWritingMessageHandler` moving the code to Java 8 style
and using `FunctionExpression`
* Fix tests according to the changed default behavior
* Add `setZsetIncrementExpression` and String-based setters for other
expressions on the `RedisStoreWritingMessageHandler`
* Add `zset-increment-expression` option for XML configuration
* Add `What's New` note on the matter
Polishing
https://build.spring.io/browse/INT-AT42SIO-502
There is a small time window when we remove the current consumer
from the local store, but there is no a new one yet.
So, we have to check the `Set`(`Map`) size before calling its `iterator`
**Cherry-pick to 4.3.x**
JIRA: https://jira.spring.io/browse/INT-4270
Initial Commit
Remove `final` modifier from certain critical framework methods that prevent CGLib proxies working.
Since Spring Boot 2.0 now uses proxyTargetClass=true by default (and has done that for
transactional proxies since 1.4), we must relax these restrictions so that CGLib can
proxy channels (which is often done to make subflows run in a transaction).
When CGLib can't override a `final` method, the fields used within those methods are uninitialized.
In the case of `AbstractMessageChannel` this causes an NPE on the unitiallized `dataTypes` field.
With `MessageHandler`, fields like `shouldTrack` are always false.
Further, methods on `IntegrationObjectSupport` - such as `getComponentName()` return null.
I have left setters and `afterPropertiesSet` (on IOS) `final` since these will typically be called
before the object is proxied.
I suspect there will be other methods we need to open up, but perhaps we should only do them on-demand.
__cherry-pick to 4.3.x__
It's difficult to subclass this mapper (e.g. to extend `toHeaders` to tweak the map)
because the factory methods for inbound and outbound mappers use private static fields
to set up the standard header mapping.
Extract that logic so that subclasses can create similar static methods and invoke the
setup code to set the standard header mapping.
Polishing: make more `DefaultHttpHeaderMapper` members available for inheritors
JIRA: https://jira.spring.io/browse/INT-4260
MPEH: Populate the `ErrorMessage.originalMessage`,
if available and not the same as the `failedMessage`.
Polishing - rename exception to `MessagingExceptionWrapper`;
make `MPEH` a subclass of `ErrorMessagePublisher`
PR Comments
Polishing - PR Comments
JIRA: https://jira.spring.io/browse/INT-4259
Since DEBUG can switched off for the application, it becomes difficult
to determine the wrong configuration for the discard flow from
the scheduler thread.
* Change logging level to the `WARN` and log the full stack-trace as well
to give more information about the reason of rescheduling group for
`forceComplete`
**Cherry-pick to 4.3.x**
JIRA: https://jira.spring.io/browse/INT-4265
* Add `.routeByError()` EIP-method to the `IntegrationFlowDefinition`
based on the `ErrorMessageExceptionTypeRouter`
* Add missed `dynamicChannelLimit()` option to the `RouterSpec`
* Rework `RouterSpec#RouterMappingProvider` into the `ContextRefreshedEvent`
phase initialization to be sure that dependent `MappingMessageRouterManagement`
is fully initialized before applying mapping conversions
* Rename `routeByError()` to `routeByException()` to more reflect reality
of the `ErrorMessageExceptionTypeRouter` and don't mislead about
Java's `Error`
* Polish `ErrorMessageExceptionTypeRouter` JavaDocs a bit and some Java 8
code style
* Add `ApplicationContext` assertion into the
`RouterMappingProvider.onApplicationEvent()` do not trigger delegate
initialization if `ContextRefreshedEvent` is from the different app context
- as discussed last week
TODO:
- should we take the channel outside of the `AbstractMessageChannel` hierarchy?
- avoid blocking interceptors
- we would lose channel metrics though
- rename `ReactiveConsumer` ?
Polishing some missed renaming
JIRA: https://jira.spring.io/browse/INT-4262
Since MySQL doesn't have `IF EXISTS` for `DROP INDEX`.
And on the other hand the entire `DROP TABLE` takes care about indexes as well,
we don't need the `DROP INDEX` command for mysql.properties
* Add `NODROPINDEX` variable to the `mysql.properties`
* Tweak `destroy.sql.vpp` to leverage `NODROPINDEX`
JIRA: https://jira.spring.io/browse/INT-4261
When we have some `Advice` withing TX Advice which may perform `doPoll()`
several times, we unconditionally call
`transactionSynchronizationFactory.create(resource)`.
With the out-of-the-box implementations
`DefaultTransactionSynchronizationFactory` and
`PassThroughTransactionSynchronizationFactory`
we preform `TransactionSynchronizationManager.bindResource()`.
If resource is already there, an `IllegalStateException` is thrown
* Check that resource isn't bound already to the TX and don't create a new
`TransactionalResourceSynchronization` - just return `null`
* Check in the target users for the `null` before registering synchronization
Move resource registration to TX outside of out-of-the-box factories
* Fix condition in the `AbstractPollingEndpoint` for the resource
* Increase responsiveness of TX test to decreasing `fixed-delay`
and using `receive-timeout="-1"`
* Upgrade to Gradle 3.5, SS-5.0, Hibernate-5.2.10, Mockito-2.7.22, Pah-1.1.1
And some other minor upgrades
* Fix deprecations for Mockito compatibility
* Fix `ServletWebSocketHandlerRegistry` deprecations
* Fix SD-Mongo deprecations
* Tweak JMX tests to avoid dangling threads after tests exist
* Increase timeouts in some polling tests
JIRA: https://jira.spring.io/browse/INT-4264
When we use Java DSL `.publishSubscribeChannel()`, we expect that subscribers
will be called in the order they are defined in the flow.
But actually everything is depend on the populated `MessageHandler` implementation.
The `AbstractMessageHandler` implements `Ordered` and according the
`OrderedAwareCopyOnWriteArraySet` logic they are placed in the beginning of the
handlers set, meanwhile all others (un-ordered) are moved to the end.
* Add implicit `.bridge()` to all the subFlows added to the `PublishSubscribeSpec`.
This way all the subFlow subscribers will be ordered the same way (because of
`BridgeHandler`) and, therefore, will be preformed in the expected (as declared) order
JIRA: https://jira.spring.io/browse/INT-4257
So that subclasses can also generate error message for conditions such
as message conversion errors.
Polishing - PR Comments
Fix JMS buildErrorMessage Override
Update Copyrights
This commit harmonizes `LockRegistry#obtain` logic in Zookeeper and JDBC
implementations with Redis implementation
by using Java 8 `ConcurrentMap#computeIfAbsent`
* Remove `synchronized (this.locks)` from the `expireUnusedOlderThan`
implementations because `iterator()` is thread-safe from `ConcurrentHashMap`
* Fix deprecation in the `IntegrationGraphControllerRegistrar`
* Revert Spring Security version to `4.2.2`, since `5.0 B-S` is broken
JIRA: https://jira.spring.io/browse/INT-4257
* Remove deprecated `EnhancedErrorMessage`
* Document `ErrorMessagePublisher` and `ErrorMessageStrategy`
* Fix Reactor version to `3.1` in Doc
* Fix sample about Reactive Streams in the `router.adoc`
JIRA: https://jira.spring.io/browse/INT-4248
To avoid unexpected double locking behavior in the cluster,
remove the local cache functionality.
Now with the new `clientId` property, the `expire` for the record in
store is always update on each lock operation
JIRA: https://jira.spring.io/browse/INT-4257
To make a target `ErrorMessage` customizable introduce
`ErrorMessagePublishingRecoveryCallback` and
`ErrorMessageStrategy` to inject
**Cherry-pick to 4.3.x**
Fix `ErrorMessagePublishingRecoveryCallback` generic type for
`RequestHandlerRetryAdvice` compatibility
Polishing
- Support publishing when no retry context is available
- Use a constant for the message context key
Add EnhancedErrorMessage
- contains input message at time of error message generation
- make the default RecovererErrorMessageStrategy public and extensible
Fix `RetryAdviceParserTests` for new `RecoveryCallback` architecture
Rename to `ErrorMessagePublisher`
Decouple ErrorMessagePublisher from Retry
Refactoring for better purpose reflection and JavaDocs
Use `ErrorMessageStrategy` in message producers.
Add JavaDocs to the `DefaultErrorMessageStrategy`
Deprecate EnhancedErrorMessage
Minor Polish for Subclass Use
- make setters final
- allow subclasses to supply the AttributeAccessor
Fix Tests
JIRA: https://jira.spring.io/browse/INT-2625,
https://jira.spring.io/browse/INT-4050,
https://jira.spring.io/browse/INT-4052
Make some refactoring for consistency:
- Move `JdbcMessageStore` to the `store` package
- Make `JdbcMessageStore` only ctor-based configuration for the `JdbcOperations`
- Remove `/channel/` SQL scripts in favor of combined in the `/jdbc/` directory
- Make scripts for the `INT_CHANNEL_MESSAGE` table and indexes generated via VPP
Fix drop script generation
Fix `schema-derby.sql` for suspicious `[]`
Looks like `foundrylogic.vpp` tool generates somehow wrong SQL
Further fix for the `drop` scripts generation
Address PR comments:
* Remove deprecated code in the `JdbcMessageStore`
* Remove separate MySQL script in favor of only one for latest version
* Remove the note in the `jdbc.adoc` about recommendation to use new MySQL version
JIRA: https://jira.spring.io/browse/INT-4254
The `LockRegistryLeaderInitiator#LeaderSelector` unconditional calls
`unlock()` in the `finally` block when the `Lock` might not be locked.
Another problem that `running = true` is set after submitting `LeaderSelector` task.
That might bring the problem that `LeaderSelector` won't be selected because of
`this.running` race condition
* Move `this.running = true` before submitting `LeaderSelector` task
* Move `unlock()` into the `if (this.locked)` condition
**Cherry-pick to 4.3.x**
* Upgrade to Jackson-2.9.0 to align with SF
* Fix `ReactiveHttpRequestExecutingMessageHandler` to use latest `WebClient`
* Introduce `Supplier<URI> uriSupplier` to evaluate the `realUri` on demand.
In case of `WebClient` use `.uri(Function)` to perform `uriSupplier`
* Move `doNext()` for the `WebClientException` out of `one-way` block.
According the `RestTemplate` logic the erroneous response is handled
before returning from the `exchange()`.
Therefore both request/reply and one-way scenarios must have the same
error handling logic
* Some refactoring to the `AbstractHttpRequestExecutingMessageHandler`
and `AbstractHttpRequestExecutingMessageHandler` according a new `uriSupplier`
Using a `LiteralExpression` in the `AbstractRemoteFileOutboundGateway` (when the
user provides a `File` for the directory) causes us to create a new `File` object
each time, instead of using the user-supplied `File`.
Use a `ValueExpression` instead.
Move the `FileWritingMessageHandler` logic to `ExpressionUtils` and use it from both places.
Also add a String setter variant for convenient Java Configuration.
https://build.spring.io/browse/INT-FATS5IC-129/
Since leader selection is done on background thread in the
`LockRegistryLeaderInitiatorTests`, there is no guarantee that
after `Thread.sleep(100)` the lock will be obtained and leader state is
changed.
* Waiting for the `granted` `CountDownLatch` is much robust condition
JIRA: https://jira.spring.io/browse/INT-4208
Since `AsyncRestTemplate` is deprecated in Spring 5.0, it doesn't make
sense to promote that feature via our new `AsyncHttpRequestExecutingMessageHandler`
component
* Rework (and rename) `AsyncHttpRequestExecutingMessageHandler` to
`ReactiveHttpRequestExecutingMessageHandler` and make it based on the
WebFlux `WebClient`
* Fix Java DSL (`ReactiveHttpMessageHandlerSpec`) and all tests according a new
logic in the `ReactiveHttpRequestExecutingMessageHandler`
* Fix XML namespace support to use new `ReactiveHttpRequestExecutingMessageHandler`
and don't expose unused options like `converters` and `request-factory`
* Fix `What's New` and `http.adoc`
* To remain with `async` mode for the `ReactiveHttpRequestExecutingMessageHandler`
behavior support fix `AbstractMessageProducingHandler` to adapt reply `Mono`
to the `SettableListenableFuture`
* Introduce new `reactive` behavior for the `AbstractMessageProducingHandler`
when `outputChannel` is `ReactiveSubscribableChannel` and perform
`.subscribeTo(Publisher)` for `Publisher` reply
* Upgrade to Spring AMQP `2.0 M3`
* Downgrade to Spring Security `4.2.2`
Address PR comments
Add async error handling to the one-way case
Minor polishing and checkstyle fix
According to some rework and deprecations in the latest Reactor,
fix Reactor-based components to follow with the latest paradigmas
* Use `Flux` wrapper in the `ReactiveChannel` to track cancellation
instead of deprecated `Operators.SubscriberAdapter`
* Do similar `Flux.from(publisher)` in the `doSubscribeTo()`
to avoid subscribers delegation and, therefore, unnecessary call stack
* Rework `ReactiveConsumer` to wrap to a new `BaseSubscriber`
on each `ReactiveConsumer.start()`.
We need this wrapping to prevent subscriber cancellation from the
upstream `Publisher` on error.
We can't rely here on the `Flux.retry()` because upstream
`DirectProcessor` is marked as terminated on any error
Apply Reactor-3.0.6.RELEASE