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
(cherry picked from commit c665405)
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-4248
The `RedisLockRegistry` doesn't update store for `expire` property on the
subsequent lock interaction.
Only `RedisLockRegistry.obtain()` lets us to know if we expired already or not
To minimize the time window between `lock` and `expire` facts, move `obtain()`
function in the `LockRegistryLeaderInitiator` close to `Lock` usage.
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**
Conflicts:
spring-integration-core/src/test/java/org/springframework/integration/support/leader/LockRegistryLeaderInitiatorTests.java
Resolved.
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
(cherry picked from commit d5c633d)
JIRA: https://jira.spring.io/browse/INT-4250
When retrieving the mean from `ExponentialMovingAverageRate` or
`ExponentialMovingAverageRatio` via `getStatistics()` the mean did not
decay over time.
The mean did decay when using `getMean()`.
This was caused by the statistics performance refactoring.
(cherry picked from commit fac04ae)
JIRA: https://jira.spring.io/browse/INT-4246
The `LockRegistryLeaderInitiator` currently does not revoke leadership
when leading instance is unable to acquire lock from the underlying lock.
This can result in multiple `LockRegistryLeaderInitiator` instances becoming
leaders in the exceptional situations such as lock timeouts.
* Handle leadership revoking when leading `LockRegistryLeaderInitiator`
is unable to acquire lock
Polish javadoc
**Cherry-pick to master**
JIRA: https://jira.spring.io/browse/INT-4229
* Make `SpelPropertyAccessorRegistrar` as `public` class and provide more API to customize it.
This class allows to register `PropertyAccessor` s for shared `EvaluationContext`
* Document how to configure SpEL functions and `PropertyAccessor` s with Java Config
**cherry-pick to 4.3.x**
JIRA: https://jira.spring.io/browse/INT-4237
It was possible to flush (close) the file while a write was in process; more likely when
`flushWhenIdle` is false.
This probably would not occur in the real world, just tests with short flush intervals,
but certainly possible.
There is already a lock used to prevent concurrent writes while appending; use the same
lock when flushing.
Conflicts:
spring-integration-file/src/main/java/org/springframework/integration/file/FileWritingMessageHandler.java
spring-integration-file/src/test/java/org/springframework/integration/file/FileWritingMessageHandlerTests.java
JIRA: https://jira.spring.io/browse/INT-4227
Expose `MessagingAnnotationPostProcessor` for inheritors.
The `CustomMessagingAnnotationTests` demonstrates how custom Messaging Annotation can be registered and used
**Cherry-pick to 4.3.x**
Add `setupCustomPostProcessors()` and `addMessagingAnnotationPostProcessor` to the `MessagingAnnotationPostProcessor`
Expose some API for inheritors
Conflicts:
spring-integration-core/src/main/java/org/springframework/integration/config/annotation/MessagingAnnotationPostProcessor.java
JIRA: https://jira.spring.io/browse/INT-4236
Add methods to obtain status from the `SmartLifecycleRoleController`.
* Polishing according PR comments.
* Fix log messages in the `SmartLifecycleRoleController` from the Zookeeper mentioning
Conflicts:
src/reference/asciidoc/endpoint.adoc
Resolved.
Also Java 6 Compatibility.
JIRA: https://jira.spring.io/browse/INT-4228
Previously, if a bean definition for a channel exists, but has configuration issues,
the `AbstractMethodAnnotationPostProcessor` still went ahead and created a `DirectChannel`.
Only with TRACE logging was the root cause apparent.
This was because all `BeanException` s cause that behavior.
Now, only `NoSuchBeanDefinitionException` will cause auto-creation of channels.
Tested with mocks and a real Boot app, which now correctly reports
```
15:28:41.582 [main] DEBUG o.s.b.d.LoggingFailureAnalysisReporter - Application failed to start due to an exception
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'rabbitConnectionFactory' available
```
* Resolve Mockito conflicts in the `MessagingAnnotationPostProcessorChannelCreationTests`
JIRA: https://jira.spring.io/browse/INT-3923Fixes: #2046
Previously, when connection is lost, the inbound adapter attempted to reconnect on
a schedule with a fixed delay.
If a connection was again lost, while the schedule is still running, we can end up
with another scheduled task running.
This is benign aside from the DEBUG log noise because the scheduled task tests the
connection before reconnecting.
However, if the `recoveryInterval` is short, it could consume CPU.
Change the reconnect to be a one-time scheduled task and reschedule if it fails to
reconnect.
Synchronize all access to the `connected` field.
Add a test case with a short recovery interval, before this fix, we see many logs
`Attempting reconnect`.
Conflicts:
spring-integration-mqtt/src/main/java/org/springframework/integration/mqtt/inbound/MqttPahoMessageDrivenChannelAdapter.java
spring-integration-mqtt/src/test/java/org/springframework/integration/mqtt/MqttAdapterTests.java
* Fix single-arg `Assert` method usage in the `AbstractCorrelatingMessageHandler`
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**
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
* Revert `java.util.Optional` import in favor of literal for Java < 8
* Make `AnnotatedTestService` as `public` to get compilable SpELs
* Remove performance test from the `MethodInvokingMessageProcessorTests`
JIRA: https://jira.spring.io/browse/INT-4203
Add channel names for easier use in DSL.
Add documentation (boot) example.
Normalize Expression Setters; add Javadocs
Polishing - SPR-15091
Tiny code style polishing
Conflicts:
spring-integration-core/src/test/java/org/springframework/integration/dsl/flows/IntegrationFlowTests.java
src/reference/asciidoc/handler-advice.adoc
spring-integration-core/src/test/java/org/springframework/integration/handler/advice/ExpressionEvaluatingRequestHandlerAdviceTests.java
* Restore removed methods in the `ExpressionEvaluatingRequestHandlerAdvice` and deprecate them
* Remove methods in the `ExpressionEvaluatingRequestHandlerAdvice` introduced since `5.0`
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`.
(cherry picked from commit 0cbfd6e)
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**
(cherry picked from commit 56929cd)
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**
(cherry picked from commit 1e46fb8)
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**
(cherry picked from commit f3460bd)
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
(cherry picked from commit a466579)
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.
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**
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.
(cherry picked from commit bd68eff)
JIRA: https://jira.spring.io/browse/INT-4163
When `MessageSource` is proxy, the `TransactionSynchronizationManager.getResource(this)` logic in the `MessageSource` doesn't work,
because TX resource is bound to the `Proxy` in the `SourcePollingChannelAdapter`
* Introduce `SourcePollingChannelAdapter.originalSource` property and store there a target `MessageSource` object extracted from the AOP Proxy
* Use `originalSource` as a resource to bind to the TX
* Modify `MongoDbInboundChannelAdapterIntegrationTests` to ensure that `AbstractMessageSourceAdvice` proxying the `MessageSource` doesn't effect `TransactionSynchronizationManager.getResource(this)` logic
* Refactor for some MongoDb test to rely on the `@RunWith(SpringJUnit4ClassRunner.class)` for context loading for better test class performance
**Cherry-pick to 4.3.x, 4.2.x**
Fallback to provided source if `target` from Proxy is `null`
Fix [UnusedImport] issue
JIRA: https://jira.spring.io/browse/INT-4144
Fixes GH-1936 (https://github.com/spring-projects/spring-integration/issues/1936)
Previously `LoggingHandler` could be used as a standalone object, without any Spring Container initialization.
Even if that doesn't sound reasonable, we should reinstate the logic to avoid breaking changes
* Initialize `expression` and `evaluationContext` during object `<init>` phase
* Some code reformatting to avoid duplicate blocks and cyclomatic complexity
* Simple code formatting
* Additional JavaDocs for `LoggingHandler`
**Cherry-pick to 4.3.x**
(cherry picked from commit ee848e9)
JIRA: https://jira.spring.io/browse/INT-4131
Specify an expression on the outbound endpoints to set the `x-delay` header when
using the RabbitMQ Delayed Message Exchange plugin.
Polishing
- PR Comments
- Add `setDelay`
- Port `FunctionExpression` from DSL
- Add `SupplierExpression`
Javadoc Fixes
Use ValueExpression for delay
* Simple polishing for `SupplierExpression`
* Mention plain `delay` property in the `amqp.adoc`
Conflicts:
spring-integration-amqp/src/test/java/org/springframework/integration/amqp/outbound/OutboundEndpointTests.java
Resolved.
Backport Polishing
Java 6 cpmpatibility; deprecation warnings.
JIRA: https://jira.spring.io/browse/INT-4132
The race condition is present when polling task may be ran before `MessageSource<?>` has been started.
* Swap the order of `start()` in the `SourcePollingChannelAdapter`.
Since proxying is now applied only for the `MessageSource.receive()` it doesn't hurt to start it before actual proxying.
Just because it is really should be started before performing its `receive()`
* Prove the proper order with the mock test and protect ourselves for the future similar changes
* Also swap the `stop()` order in the `SourcePollingChannelAdapter.
We have to stop/cancel the polling task before discarding internal `MessageSource` lifecycle.
For example with the current state we may close an underlying resource already, but still have the last polling tick.
That may cause any unexpected behaviour
**Cherry-pick to 4.3.x**
Polishing
JIRA: https://jira.spring.io/browse/INT-4113
* To simplify `MessagePublishingErrorHandler` and avoid extra `PollerMetadata` beans, added the `errorChannel()` attribute to the `@Poller` annotation
* The `MessagePublishingErrorHandler` now supports the late-binding via new `defaultErrorChannelName`
* Docs about new `errorChannel()` attribute
* Some other docs polishing
Polishing
**Cherry-pick to 4.3.x**
Polishing docs according PR comments
Conflicts:
spring-integration-core/src/main/java/org/springframework/integration/config/annotation/AbstractMethodAnnotationPostProcessor.java
Resolved and reworked Java8 features in tests.
JIRA: https://jira.spring.io/browse/INT-4120
INT-3899 moved creating the pollingTask to start() to allow modification
of the advice chain between starts.
Since a new pollingTask is created on each start, this was fine for general advices.
However, for `AbstractMessageSourceAdvice`s, which only advise the `receive()` operation,
the advices are re-applied on every start.
When starting, first remove any advices we added on the previous start.
This handles the case when the source is a naked object, or already a proxy when supplied
to the SPCA.
Remove uneeded cast
Polishing - PR Comments
JIRA: https://jira.spring.io/browse/INT-4096
* Introduce `spring.integration.readOnly.headers` Integration property
* Introduce `IntegrationMessageHeaderAccessor.setReadOnlyHeaders()` and use it from the overridden `IntegrationMessageHeaderAccessor.isReadOnly()`
* Add `DefaultMessageBuilderFactory.setReadOnlyHeaders()` and delegate the value to the new `MessageBuilder.readOnlyHeaders()`
* Modify `spring.integration.properties` for the `contentType` as a `readOnly` header for testing
* Ensure that provided logic works via an appropriate modification to the `ObjectToJsonTransformerParserTests`
Increase receive timeouts in the `OutboundGatewayFunctionTests`
Fix `FileInboundTransactionTests` for slow `WatchService` issue on Linux/OS X
Also redo the `tmp` dir logic to the `TemporaryFolder` `@ClassRule`
Fix unused `import` in the `FileInboundTransactionTests`
Polishing
JIRA: https://jira.spring.io/browse/INT-4108
Some `Lifecycle.start()/stop()` usage doesn't ensure robustness for components causing unexpected and difficulty tracing issues
* Fix `Lifecycle.start()/stop()` for `FileReadingMessageSource`, `FileWritingMessageHandler`, `AbstractMqttMessageHandler`
* In the `DefaultHeaderChannelRegistry`, `LockRegistryLeaderInitiator`, `MqttPahoMessageHandler` rework logic for shared variables to avoid `NPE`
* Increase receive timeouts in the `PayloadDeserializingTransformerParserTests` and `UdpChannelAdapterTests`
* Prove with the `WatchServiceDirectoryScannerTests` changes that several invocation for `FileReadingMessageSource.start()` are idempotent
**Cherry-pick to 4.3.x**
https://build.spring.io/browse/INT-SI43X-6/
Since Exponential Moving Average algorithm is fully based on the time in between events, it is very difficult to reach the stable tests.
All of them used to fail from time to time on the slow CI server.
Mark all Exponential Moving Average Tests with `@Ignore`.
The manual testing is required in case of some changes.
**Cherry-pick to 4.3.x**
(cherry picked from commit 76bb3ad)
JIRA: https://jira.spring.io/browse/INT-4078
Even if it doesn't hurt to `copyHeadersIfAbsent()`, when it just adds a new headers and doesn't override existing like sequence details,
it doesn't sound reasonable for `Resequencer` to modify the message before and after its resequence logic.
* Change `shouldCopyRequestHeaders()` to `false` for `ResequencingMessageHandler`
JIRA: https://jira.spring.io/browse/INT-4064
We configure `IdempotentReceiver` via `<int:idempotent-receiver>` component or `@IdempotentReceiver` annotation.
In case of regular Java config, e.g. direct `ConsumerEndpointFactoryBean` usage or Java DSL,
it isn't possible to configure `idempotentReceiverInterceptor` enough easy
* Introduce `if...else` logic into `ConsumerEndpointFactoryBean` to proxy `MessageHandler`,
if `adviceChain` contains an newly-introduced `HandleMessageAdvice`.
And do that independently if `MessageHandler` is `AbstractReplyProducingMessageHandler`
* Make `idempotentReceiverInterceptor extends HandleMessageAdvice`
* Skip `HandleMessageAdvice` in the `AbstractReplyProducingMessageHandler`
* Add advice applying logic into the `AbstractMethodAnnotationPostProcessor` as well
Introduce `HandleMessageAdvice` marker interceptor to cover the case when an `Advice` can be advices as well.
Remove unused `setAdviceChainIfPresent()` method in the `AbstractMethodAnnotationPostProcessor`
Document `HandleMessageAdvice`
Increase wait latch timeouts in the `LockRegistryLeaderInitiatorTests`
Doc Polishing