To avoid confusing `.bridge(null)` in the end of flow for replying to the gateway on top introduce simple `.bridge()` with just delegation to the `.bridge(null)` with the same result as before
JIRA: https://jira.spring.io/browse/INT-4222
See INT-4214; the `DefaultMessageHandlerMethodFactory` requires a conversion service
and sets up a default.
Some SI components propagated a `null` conversion service which overwrote the default
causing runtime exceptions.
Caused by: java.lang.IllegalArgumentException: ConversionService must not be null
at org.springframework.util.Assert.notNull(Assert.java:163) ~[spring-core-5.0.0.BUILD-SNAPSHOT.jar:5.0.0.BUILD-SNAPSHOT]
JIRA: https://jira.spring.io/browse/INT-4220
Currently when an error is thrown from the event publishing the role granting is broken and we just go to the role revoking.
* Since it's just an event publishing it shouldn't effect the original leader election.
* `try...catch` event publishing in the `LeaderInitiator` and `logger.warn` an `Exception`
* Make `leader/Context` as `@FunctionalInterface` for simple Lambda use-case like `NULL_CONTEXT` - `() -> false`
* Remove all the internal `NullContext` implementations in favor of above mention Lambda
* In the `LockRegistryLeaderInitiator` use `CustomizableThreadFactory` instead of custom `ThreadFactory` for prefixing
* Add `zookeeper/leader/LeaderInitiator#getContext()` for external usage and consistency with other similar components
* Fix `CuratorContext.toString()` typo
JIRA: https://jira.spring.io/browse/INT-4221
* Upgrade to those versions of Spring project dependencies which potentially will provide similar fix
**Cherry-pick to 4.3.x**
Fixesspring-projects/spring-integration-java-dsl#140
Allow to provide any custom `MessageProducer` impl for the `.handle()`, not only `AbstractReplyProducingMessageHandler` extension
Polishing
JIRA: https://jira.spring.io/browse/INT-4217
Previously, SpEL method calls with required header parameters had the following form:
#target.messageAndHeader(message, headers['number'] != null ? headers['number'] : T(org.springframework.util.Assert).isTrue(false, 'required header not available: number'))
The SpEL compiler cannot compile this because the else clause of the ternary has no `exitDescriptor` to indicate the type.
Change the expression to use a function for required headers.
Also use an Elvis operator when possible.
Some examples of new expressions:
#target.optionalAndRequiredHeader(headers['prop'] ?: null, #requiredHeader(headers, 'num'))
#target.optionalAndRequiredDottedHeader(headers['dot1'] != null ? headers['dot1'].foo : null,
#requiredHeader(headers, 'dot2').baz
In the second case, we can't use an Elvis because we're accessing a `foo` property of the header.
__cherry-pick to 4.3.x__
- make `ParametersWrapper` `static`
- minor conflicts in imports
- remove the perf test
* Polishing: remove redundant annotation args for their default values usage
Several problems:
- Setting the system property is not enough since the `static` parser already has its configuration
- Changing the ParametersWrapper to `private` makes property accessing not compilable (the method and class must be public).
- The expression...
#target.messageAndHeader(message, headers['number'] != null ? headers['number'] : T(org.springframework.util.Assert).isTrue(false, 'required header not available: number'))
...is not compilable anyway because the right arguent to the `!=` is not compilable because the `TypeReference.exitTypeDescriptor` is `null`.
This commit addresses the first two.
Polishing
Use a compilable method.
* Simple polishing
JIRA: https://jira.spring.io/browse/INT-4214
* Rework `MessagingMethodInvokerHelper` to delegate to the `InvocableHandlerMethod` with its `HandlerMethodArgumentResolver` infrastructure instead of SpEL
* Introduce several `HandlerMethodArgumentResolver` to address some SI use-cases like `@Payloads`, `@Payload(expression = "")` and `Collection` as argument
* Initialize `DefaultMessageHandlerMethodFactory` in the `MessagingMethodInvokerHelper.start()`.
With that I observed several `Lifecycle` problem when we don't have proper delegate from the top.
* Fix `AbstractCorrelatingMessageHandler` and similar to delegate `Lifecycle` properly
* Fix `ReactiveConsumer` to delegate `Lifecycle` to the `MessageHandler`
* Fix `MutableMessage` do not `generateId()` and set `timestamp` headers if we already have them in the provided headers
* With all that `Lifecycle` many tests must be fixed to call `start()`
Add SpEL fallback variant to the MessagingMethodInvokerHelper
Add `MessagingMethodInvokerHelper.setUseSpelInvoker(boolean)`
Add `MethodInvokingMessageProcessorTests.testPerformanceSpelVersusInvocable()`
Add Compiled SpEL comparison
* Add `MapArgumentResolver` to cover `Properties` case
* add `MessagingMethodInvokerHelper.HandlerMethod.spelOnly` state, when we definitely can perform ony SpEL for provided arguments, e.g. `@Header` with expression
* Catch `IllegalStateException` with the `"argument type mismatch"` message to fallback to SpEL invocation
* Add `Iterator` support for the `CollectionArgumentResolver`
* Add `integrationConversionService` bean registration into the `TestUtils.createTestApplicationContext()`
* Tweak `.travis.yml` to try to download latest JDK, the current `1.8.0_31` is pretty old already and has some bugs
* Adjust some failing tests to use `TestUtils.createTestApplicationContext()` to rely on newly added `integrationConversionService` bean
Fix failed tests: `ctx.refresh()`
Polishing current year in Copyright
* JavaDocs for `CollectionArgumentResolver` and `MapArgumentResolver`
* Propagate `ConversionService` from the `MessagingMethodInvokerHelper` to the `MapArgumentResolver.java`
Fix `MessagingMethodInvokerHelper` to propagate `BeanFactory` into `MapArgumentResolver` as well
The `MapArgumentResolver` now `extends AbstractExpressionEvaluator`, too
Fix JavaDoc typo
Otherwise we end up with the case to break the flow which expect message from the explicit channel.
Add JavDocs to `.wireTap()` to explain behaviour in the end of flow
JIRA: https://jira.spring.io/browse/INT-4210
Previously use-case like:
```
.transform()
.log()
.get();
```
failed with the `Dispatcher has no subscribers` for an implicit channel populated by the `.wireTap()` because actually `LoggingHandler` is placed on the wire-tapped channel
Since logically it looks like end-user tries to have `LoggingHandler` as a terminal of the flow, we add `nullChannel` if `WireTapSpec` is in the end of the flow definition.
If user would like to continue flow (e.g. return reply to the `replyChannel`), he must end more EIP-methods after `.log()` (like before, of course)
JIRA: https://jira.spring.io/browse/INT-4207
Enhance `AbstractMessageProducingHandler` to fallback for `replyChannel` to the `reply` if it is `Message`.
That lets to avoid extra `bridge` configuration afterwards to make that `reply` as `request` for the same `replyChannel` resolution.
This situation happens in case of error handling when the request message is `ErrorMessage`, typically without original headers to properly consult.
But at the same time `failedMessage` in the `MessagingException` has all required headers.
JIRA: https://jira.spring.io/browse/INT-4206
* Fix unnecessary dependency resolution in BOM module
* Fix `MessagingMethodInvokerHelper` to handle `$MockitoMock$` generated classed which isn't CGLib `Proxies` any more
* Provide fixes for test classes according upgrade to Mockito `2.5`
* Fix Ceckstyle do not allow static imports for deprecated Mockito classes
* Move `SubscribableChannelPublisherAdapter` and `PollableChannelPublisherAdapter` logic to the `MessageChannelReactiveUtils` public API
* Rework `ReactiveConsumer` and `IntegrationFlowDefinition.toReactivePublisher()` to use `MessageChannelReactiveUtils`
* Add `ReactiveSubscribableChannel` interface to represent abstraction with capability to subscribe to `Publisher`
* Implement `ReactiveSubscribableChannel` in the `ReactiveChannel`
* Add `IntegrationFlows.from(Publisher)` factory and use newly introduced `ReactiveSubscribableChannel.subscribeTo()`
* Add `MessageChannels.reactive()` factory methods for the `ReactiveChannelSpec`
* Make `ReactiveChannel` as an `AbstractMessageChannel` to give an interception opportunity and gather metrics for `send()`
* A `ReactiveStreamsTests.testFromPublisher()` demonstrate how to subscribe to the `Flux` from an `IntegrationFlow` and at the same time get a gain of the runtime flow registration
* The `ReactiveChannelTests.testMessageChannelReactiveAdaptation()` demonstrates how to use `MessageChannelReactiveUtils.toPublisher()` (name can be changes though...)
JIRA: https://jira.spring.io/browse/INT-4134
* Introduce `AnnotationGatewayProxyFactoryBean` to parse `@MessagingGateway` annotation directly in the bean.
Useful for Java (`@Bean`) configuration variant
* Use `AnnotationGatewayProxyFactoryBean` for the newly introduced `IntegrationFlows.from(Class<?>)`
* Override `requestChannel` in the result gateways to the auto-created `DirectChannel` in the current `IntegrationFlowDefinition`
* Register `AnnotationGatewayProxyFactoryBean` from the `IntegrationFlows.from(Class<?>)` as a bean with the name like: `IntegrationFlow` bean name plus `.gateway` suffix
* Merge `GatewayCompletableFutureProxyFactoryBean` to `GatewayProxyFactoryBean`, since we are based on the Java 8 already anyway
JIRA: https://jira.spring.io/browse/INT-4197
Since `Collection<Message<?>>` can be possible only if we are dealing with messages as a group (`MethodInvokingMessageListProcessor`), the case with the `List<?>` param for Messaging Annotation method should not be treated as candidate for `messages` collection.
* Add `this.canProcessMessageList` condition to avoid `messages` SpEL expression when we are not in the `MethodInvokingMessageListProcessor` environment
**Cherry-pick to 4.3.x**
* Fix Array creating formatting
* Add comment about `ReflectiveMethodExecutor` to the `testRouterWithListParam()`
* Send one test data as as `Collection` to be sure that `@Router` parameters mapping works well
JIRA: https://jira.spring.io/browse/INT-4201
name<->value alias was not processed correctly so using
`@Header(name = "baz") String baz` did not work.
Use `SynthesizingMethodParameter`.
JIRA: https://jira.spring.io/browse/INT-4196
Add `CollectionCallback` option to the `MongoDbOutboundGateway`
Add XML support to CollectionCallback
Fix PR comments
Fix issue with javadoc parsing
* Polishing code style, JavaDocs and some Docs
There is tiny time window when `LockRegistryLeaderInitiator` can be stopped during `Context.yield()` invocation.
In this case the `LockRegistryLeaderInitiator` goes to the stopped state, but a new `leaderSelector` is submitted for election.
Therefore in the `LockRegistryLeaderInitiatorTests.competing()` the second initiator may not get be granted because there is uncontrolled `leaderSelector` task on background.
We can overcome it with always `this.initiator.stop()` for the `LockRegistryLeaderInitiatorTests`, but to be sure in the fix it would be better to leave as is.
Also add `@Rule Log4jLevelAdjuster` for future diagnostics
**Cherry-pick to 4.3.x**
No reason to load class one more time if `MethodMetadata` is already `StandardMethodMetadata`
See https://jira.spring.io/browse/SPR-14505
**Cherry-pick to 4.3.x**
https://build.spring.io/browse/INT-MJATS41-856
According the attempts to read method from class in the proper order, there is a fix in SF to do that via ASM.
Therefore `beanDefinition.getSource()` isn't `StandardMethodMetadata` any more.
Fortunately we can simply assert against `returnTypeName` to check for the `MessageHandler`
See https://jira.spring.io/browse/SPR-14505
**Cherry-pick to 4.3.x**
Fixes GH-2007 (https://github.com/spring-projects/spring-integration/issues/2007)
To allow more straightforward extension and avoid some extra mocking provide some `protected` methods for the `IntegrationComponentScanRegistrar` which can be implement in some specific cases, like Spring Boot auto-configuration
The `EnableComponentScanTests` demonstrates how it can be done now in case of `basePackage` overriding
JIRA: https://jira.spring.io/browse/INT-4195
Avoid the N^2 search in `SequenceAwareMessageGroup` when the group is a
`SimpleMessageGroup`.
Avoid the use of the header accessor if the N^2 search is needed (SPR-15045).
Polishing - PR Comments
JIRA: https://jira.spring.io/browse/INT-4193
When using the internal `SequenceAwareMessageGroup` within an correlating
message handler, the messages were copied to a new collection before
checking for duplicate sequences in `canAdd()`.
This was unnecessary since we never add anything to this group, if `canAdd()`
returns true, the message is added to the store; this group is discarded.
Instead, use the message collection from the original group; although it is
not modifiable, this is not an issue because we don't need to modify it.
Conflicts:
spring-integration-core/src/main/java/org/springframework/integration/store/SimpleMessageGroup.java
spring-integration-core/src/main/java/org/springframework/integration/store/SimpleMessageGroupFactory.java
src/reference/asciidoc/aggregator.adoc
* Polishing `aggregator.adoc` to reflect reality
https://build.spring.io/browse/INT-MASTER-478
The `EmitterProcessor` proves to be unstable in between subscribers which come and go away from time to time.
Looks like buffered events are dropped when we don't have subscriber just after the previous one has been unsubscribed
* Change the logic in the `IntegrationFlowDefinition.toReactivePublisher()` to call `ReactiveConsumer.adaptToPublisher(MessageChannel)` directly to return provided `Publisher<?>` to the caller for his own responsibility.
This way we don't have any buffering or prefetching in the Framework because we don't do any `Subscription.request(n)` explicitly
* Prove the fix with polishing to the `ReactiveStreamsTests.testPollableReactiveFlow()`
Right now we don't poll `QueueChannel` if there is no demand, therefore we don't need extra `CountDownLatch` to wait for second subscriber.
Plus the logic now remains as a `queue` manner: consumers are concurrent for the data in the `QueueChannel`
Extra `@Repeat(10)` for confirmation.
Previously it failed sporadically, what is confirmed with that one more CI failure
JIRA: https://jira.spring.io/browse/INT-4181
* To avoid duplicate code move actual `Metrics` resolution to the `IntegrationManagementConfigurer` and delegate from the `IntegrationMBeanExporter` for backward compatibility
* Minor refactoring and improvements in the `IntegrationMBeanExporter`
* Fix typos in the `jms/AsyncGatewayTests`
**Cherry-pick to 4.3.x**
https://build.spring.io/browse/INT-MASTER-473/
There is a race condition when we perform `onSubscribeCall()`, but the actual subscription isn't happened yet, therefore a new data for the `EmitterProcessor` is dropped because there is no subscriber yet to drain the buffer
JIRA: https://jira.spring.io/browse/INT-4182
To avoid extra allocation for the `SimpleDateFormat` use a new Java 8 `DateTimeFormatter` based on new `Temporal` abstraction
Leave test-cases as is to save some time for other tasks
Fix RedisLockRegistry for the proper formatter and ZoneId
https://build.spring.io/browse/INT-MASTER-468/
Looks like demand in the `FluxTake` isn't honored:
```
public void request(long n) {
if (wip != 0) {
s.request(n);
}
else if (WIP.compareAndSet(this, 0, 1)) {
if (n >= this.n) {
s.request(Long.MAX_VALUE);
}
else {
s.request(n);
}
}
}
````
It isn't clear why we request from upstream `Long.MAX_VALUE`, if we have only strong `n` limit
So, revert to the `secondSubscriberLatch` and don't send the next message until the subscription from the second `Flux`
https://build.spring.io/browse/INT-MASTER-467/
Even if `EmitterProcessor` looks good for us not requesting until real `subscriber()`, it doesn't keep backlog for late subscribers like it happens some times in our subscriber in the separate Thread.
The solution should be considered as tentative because the real one must be based on the fact that `AMPH` has to perform `subscription.request(n)` as a fact of the subscription from downstream.
In other words mid-flow components should work as passive subscribers and be based on downstream demand
Change all the `BUILD-SNAPSHOT`s to their latest Milestones
Fix compatibility with those Milestones
Upgrade to Spring AMQP 2.0.0.M1
Upgrade to Spring Data Kay
Gemfire now is based on the Apache Geode, so changed all the imports to proper new packages
MongoDB now is based on the Mongo 3 Driver, therefore many breaking changes. Mostly to the mapping part
Fix Checkstyle violation
Fix race condition in the `MongoDbInboundChannelAdapterIntegrationTests` around `QueueChannel` and tx commit
Add `-s` to Travis Gradle command to see stack trace about `MongoDbMetadataStoreTests` problem
Test only MongoDB module on Travis with -d
Add addon to Travis to pull MongoDB-3.0
Fix `MongoDbAvailableRule` for MongoDB 3.0 Driver style
Increase `serverSelectionTimeout` to `100` in the `MongoDbAvailableRule`.
Looks like `0` isn't good value to get immediate answer
The `BridgeHandler` is Reactive `Subscriber` with `MAX_VALUE` demand just `onSubscribe()`.
That causes a drain of the upstream `QueueChannel` to the `ReactiveChannel` with `DirectProcessor`.
The last one just drops messages if there is no subscribers
`EmitterProcessor` doesn't request upstream until real subscriber arrives to it.
Therefore change `BridgeHandler` logic in the `IntegrationFlowDefinition.toReactivePublisher()` to the `EmitterProcessor` to allow late `Subscriber`s and don't lose messages from the `QueueChannel` if there is no downstream `Subscriber`s
JIRA: https://jira.spring.io/browse/INT-4174
I considered just using the channel counter but I suppose there is a (small) possibility
that someone might possibly use a custom dispatcher and subscribe to it directly.
Polishing -- ** master only **
Eliminate conditional logic in AbstractMessageChannel by adding getHandlerCount() to
MessageDispatcher.
Do not cherry pick.
* Also fix JPA tests model for proper database `sequence` to avoid race condition when the test data is inserted with lower `id` than expected predefined data has
https://build.spring.io/browse/INT-MASTER-444/
Looks like we still need `method.setAccessible(true)` in the `LambdaMessageProcessor` even if method is `public`.
I think the problem is because any Lambda is still **inline class**, so even if method is `public`, the class isn't
Fix CheckStyle violations and one more `isLambda()`` in the `RecipientListRouterSpec`
Add `Assert` for method ambiguity to the `LambdaMessageProcessor` to be sure that we get deal only with the Function Interface impl
Since the DSL code is new in this version there is no reason to keep deprecated method
* Remove deprecated `resequence()` and `aggregate()` in the `IntegrationFlowDefinition`
* Remove `InternalAggregatingMessageHandler` with the `MessageGroupProcessorWrapper` delegation logic in favor of newly introduced `AbstractCorrelatingMessageHandler.setOutputProcessor()`
* Rework `Promise` Gateway Docs to the `Mono`
* Rename `AsyncGatewayTests` "promise" words to "mono"
* Resolve `com.rabbitmq.client.FlowListener` deprecation
RecipientListRouter DSL refactoring
Previously there was a DSL specific `DslRecipientListRouter` to overcome the lack of setters in the target `RecipientListRouter` and its `Recipient`
* Add `channelName` variant for the `Recipient`
* Add several new `addRecipient()` methods to the `RecipientListRouter`
All those improvements allow to avoid extra bridge (or adapter) component between Java DSL and target `RecipientListRouter`
* Make `LambdaMessageProcessor` and `GatewayMessageHandler` as `public` classes and move them to the appropriate packages
Address PR comments
Add `isLambda()` condition to `RecipientListRouterSpec` to avoid ambiguity for the provided `GenericSelector` impl
checkstyle polishing
JIRA: https://jira.spring.io/browse/SPR-14948
The `StandardTypeConverter` no longer has a `defaultConversionService` field, it uses
a static instance from `DefaultConversionService`.`
https://sonar.spring.io/component_issues?id=org.springframework.integration%3Aspring-integration%3Amaster#resolved=false|types=BUG
In `IntegrationFlowRegistration` double check locking is ok for `inputChannel`
because we're assigning an existing object, but `MessagingTemplate` constructs
a new object for which double check locking doesn't work.
In any case, for both these items, the chance of concurrent access is extremely low
and is idempotent anyway, so remove double check locking.
Several inner classes can be static.
Other minor fixes.
JIRA: https://jira.spring.io/browse/INT-4158
* Add JavaDocs
* De-Boot `JpaDslTests`
* Fix typos and generics inconsistency in the `JpaOutboundGatewayFactoryBean`
Address PR comments
* Get rid of `JpaOutboundGatewayFactoryBean` usage in the `JpaBaseOutboundEndpointSpec`
* Rework `JpaBaseOutboundEndpointSpec` and its inheritors logic to use `JpaOutboundGateway` directly
* Rename to the `JpaTests`
* Fix JavaDoc in the `IntegrationFlowDefinition`
* Do not use `jpaParameters` in the `JpaExecutor` if it is empty collection, not only null