* INT-4565: Fix IntComponentScan for profiles
JIRA: https://jira.spring.io/browse/INT-4565
* Propagate an `Environment` to the internal `ClassPathScanningCandidateComponentProvider`
in the `IntegrationComponentScanRegistrar` for proper profiles activation
* Ensure the logic works in the `GatewayInterfaceTests`
* Some polishing and performance improvement for the `GatewayInterfaceTests`
* Add a note about `@Profile` in the `gateway.adoc`
* Polishing for the `gateway.adoc`
**Cherry-pick to 5.0.x & 4.3.x**
* * Add not activated by profile gateway interface into the `GatewayInterfaceTests`
* More `GatewayInterfaceTests` polishing
* Fix typo in the `gateway.adoc`
* Fix Checkstyle violation
# Conflicts:
# spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayInterfaceTests.java
# src/reference/asciidoc/gateway.adoc
JIRA: https://jira.spring.io/browse/INT-4564
INT-4550 added an error log when multiple ACMHs were registered with the
same store; the error log logic was incorrect and the error was logged
when the first ACMH was registered.
(cherry picked from commit 9832f61d2a)
JIRA: https://jira.spring.io/browse/INT-4556
We definitely need to resolve a `@Bean` method to the target object to
be sure do not create a new `MessageHandler` bean.
**Cherry-pick to 5.0.x**
* INT-4550: Disallow multi aggregators on same MGS
JIRA: https://jira.spring.io/browse/INT-4550
**Cherry-pick to 5.0.x**
* * Introduce `UniqueExpiryCallback`
* Use `UniqueExpiryCallback` in the `AbstractCorrelatingMessageHandler`
* Check for uniqueness in the `AbstractMessageGroupStore`
* Remove duplicate code in the `ConfigurableMongoDbMessageStore`
* * Fix tests according a new logic
* * Address PR review
* Change `Assert.isTrue` to the `logger.error` for backward compatibility
* Revert changes in tests since we don't throw exception anymore
* Fix language on doc
* * Fix Checkstyle violation in the `AbstractMessageGroupStore`
* * Ignore `testDontReapMessageOfOtherHandler()`
JIRA: https://jira.spring.io/browse/INT-4545
Improve the logic in the `AbstractMethodAnnotationPostProcessor` to
check for existing `MessageHandler` and be sure that we need to register
a `ReplyProducingMessageHandlerWrapper` bean
**Cherry-pick to 5.0.x**
* INT-4543: JacksonJsonObjectMapper: fix toJsonNode
JIRA: https://jira.spring.io/browse/INT-4543
When inbound payload is type of `String`, `byte[]`, `File`, `URL`,
`InputStream` or `Reader`, we have to use an `ObjectMapper.readTree()`
function.
For all other types the `valueToTree()` should be used as a fallback
**Cherry-pick to 5.0.x**
* * Fallback to the `valueToTree()` if not valid JSON
* * Fallback to `valueToTree()` only for `String` and `byte[]`
JIRA: https://jira.spring.io/browse/INT-4541
Add test case to reproduce.
The gateway correctly sets up the `errorChannel` header so that a downstream
`MPEH` will send exceptions back to the gateway, but the `map()` function
did not check for an error message.
Check for an error message and throw the payload so that the `onErrorResume`
will route to the error channel.
# Conflicts:
# spring-integration-webflux/src/test/java/org/springframework/integration/webflux/dsl/WebFluxDslTests.java
JIRA: https://jira.spring.io/browse/INT-4538
* Add support for Jackson `TreeNode.size()` in the `AbstractMessageSplitter`
* Add overloaded `Transformers.toJson(ObjectToJsonTransformer.ResultType)`
* Modify test to verify Jackson `ArrayNode` use-case with the splitter
and aggregator
**Cherry-pick to 5.0.x**
JIRA: https://jira.spring.io/browse/INT-4539
The `IntegrationFlowBeanPostProcessor` doesn't check for prototype beans
and just override them in the application context with the singletons
* Since we can't in the DSL understand if provided object is a prototype
or not, we try to check for its bean definition by possible bean name.
Use `NamedComponent` for possible bean name to check.
* Remove `final` from the `IntegrationComponentSpec.get()` since its
result is not visible for CGI proxies when it is declared as a `@Bean`
and subsequent `getObject()` produces a new internal object
* Verify prototype beans with new test in the `IntegrationFlowTests`
**Cherry-pick to 5.0.x**
JIRA: https://jira.spring.io/browse/INT-4537Fixesspring-projects/spring-integration#2582
* Rename `ReactiveStreamsConsumer.messageHandler` property to the
`handler` for consistency with other `IntegrationConsumer` s
* Do not wrap `Subscriber` into the `MessageHandler` if that one is
already a `MessageHandler`
* Fix `MockIntegrationContext` for the logic around `ReactiveStreamsConsumer`
where it is not enough just replace a `handler`, but we also need to do
that with the `subscriber`.
Luckily the `MockMessageHandler` is also a Reactive `Subscriber`
* Clean up `MockIntegrationContext.beans` in the end of `resetBeans()`
* Improve `testing.adoc`
**Cherry-pick to 5.0.x**
* Add Micrometer metrics capture for the
`PollableAmqpChannel` and `PollableJmsChannel`
* Polishing and optimization for the `AbstractPollableChannel.receive()`
**Cherry-pick to 5.0.x**
JIRA: https://jira.spring.io/browse/INT-4527
Fixes https://github.com/spring-projects/spring-integration/issues/2543
- Add error handling within the scope of a transaction
- Add `retryDelay` and `maxAttempts`
- Include the delivery attempt header in the `ErrorMessage`
- Add `transactionalRelease()` methods to the DSL
Check context in `ContextRefreshedEvent`.
Complete test case; don't schedule for re-release after a successful send after a failure.
Use `identityHashCode` for deliveries map key - error flow might change the message `hashCode`.
Debug logging
Polishing; remove parameter from the `DelayerEndpointSpec.transactionalRelease()`
* Polishing some code style
# Conflicts:
# src/reference/asciidoc/delayer.adoc
There is a race condition when Zookeeper `LeaderInitiator` may start
earlier than `CuratorFramework` it depends on.
This is because both of them are configured for the same default `phase` (`0`)
* Make `LeaderInitiator` and `LockRegistryLeaderInitiator` to be started
in the `Integer.MAX_VALUE - 1000` phase by default - as late as possible
* Make `CuratorFrameworkFactoryBean` to start in the `Integer.MIN_VALUE + 1000`
phase - as early as possible
* Alight lifecycle properties from the `LeaderInitiatorFactoryBean` with
defaults in the `LeaderInitiator`
* Simplify a `LeaderListenerParser` to rely on the `LeaderInitiatorFactoryBean`
**Cherry-pick to 5.0.x**
JIRA: https://jira.spring.io/browse/INT-4518
* Fix `BridgeFromAnnotationPostProcessor` do not resolve `outputChannel`
for the target `BridgeHandler`
* Rework logic in the `AbstractMethodAnnotationPostProcessor` to do not
resolve a `MessageHandler` bean from the `@Bean` method when we can
just check a method return type.
* Check `BeanDefinition` instead of real bean when we consult for
conditions
**Cherry-pick to 5.0.x**
* Fix memory leak in MHistorConfig & MBeanExpHelper
The `MessageHistoryConfigurer` is a `BeanPostProcessor` which keeps a
store of the `TrackableComponent`.
Something similar we have with the `MBeanExporterHelper` and its local
stores populated by the `postProcessBeforeInitialization()`
* Implement `DestructionAwareBeanPostProcessor` in the
`MessageHistoryConfigurer` and `MBeanExporterHelper` to remove destroyed
beans from their caches
**Cherry-pick to 5.0.x**
* * Fix concurrency and checkstyle
* Apply Java 8 style for collections iterations
JIRA: https://jira.spring.io/browse/INT-4513
The `IntegrationManagementConfigurer` keeps metrics beans in its local
stores.
When we add beans at runtime, they are not removed from those caches
after their removal
* Implement `DestructionAwareBeanPostProcessor` in the `IntegrationManagementConfigurer`
and clean up caches according provided bean type and its name
* Improve `ManualFlowTests` and `FtpTests` to be sure that
`IntegrationManagementConfigurer` caches are cleared after destroying
`IntegrationFlowRegistration`
**Cherry-pick to 5.0.x**
JIRA: https://jira.spring.io/browse/INT-4514
`getBeansOfType()` with eager init does not currently return late registered singletons.
We should not be eagerly initializing here anyway.
**cherry-pick to 5.0.x**
# Conflicts:
# spring-integration-core/src/main/java/org/springframework/integration/support/management/graph/IntegrationGraphServer.java
JIRA: https://jira.spring.io/browse/INT-4510
Related to https://github.com/reactor/reactor-core/issues/1290
The `Flux.publish()` and subsequent `connect()` doesn't fuse a subscriber
for the hooks flow is interrupted (complete, or error, or disconnect).
In this case the `FluxMessageChannel.publishers` store is not cleared
from the finished publishers
* Add test-case to check the `FluxMessageChannel.publishers` store after
finishing the stream
* Add `hide()` operator with TODO to remove when an appropriate Reactor
version is ready
**Cherry-pick to 5.0.x**
JIRA: https://jira.spring.io/browse/INT-4509
To avoid a re-usage of the `AbstractReplyProducingMessageHandler`,
the `IntegrationFlowDefinition` and `AbstractStandardMessageHandlerFactoryBean`
have a `static Set<>` to store already used producers and check it for
newly provided.
These stores are not cleaned when beans are destroyed leading to memory
leaks
* Implements a `DisposableBean` for the `AbstractStandardMessageHandlerFactoryBean`
to remove its `replyHandler` from the `referencedReplyProducers` on
`destroy()`
* Introduce a `IntegrationFlowDefinition.ReplyProducerCleaner` - an
`DestructionAwareBeanPostProcessor` to clean up removing `MessageProducer`
from the `IntegrationFlowDefinition.REFERENCED_REPLY_PRODUCERS`
**Cherry-pick to 5.0.x**
JIRA: https://jira.spring.io/browse/INT-4506
Capture the actual splitter result in the `FunctionIterator and close it if necessary.
**cherry-pick to 5.0.x**
Add Closeable to proxy in test; remove AutoCloseable check.
Closeable extends AutoCloseable.
Fix javadocs; test for AutoCloseable instead of Closeable
Polishing - PR comments; tighten up API.
A `CloseableIterator` is now an `AutoCloseable` with an overridden
`close()`` (no exception) to avoid lint problem.
* Polishing omissions, code style and `@author`
**Cherry-pick to 5.0.x**
(cherry picked from commit bebde26)
JIRA: https://jira.spring.io/browse/INT-4501
The call to the `IntegrationFlowBeanPostProcessor#setBeanFactory`
happens during BPP creation.
The introduced call to `beanFactory#getBean` triggers a lot of bean
creations.
For those beans not all `BPP`s are applied.
* Obtain a `flowContext` bean in lazy-load manner
**Cherry-pick to 5.0.x**
Since `IntegrationComponentSpec` is a `FactoryBean`, we need to care
about `Aware` and `init` & `destroy` hooks our selves or delegate
them through the `FactoryBean` wrapper
* Implement `InitializingBean` and `DisposableBean` on the
`IntegrationComponentSpec`
* Call the `Aware` hooks from the `IntegrationFlowBeanPostProcessor`
**Cherry-pick to 5.0.x**
JIRA: https://jira.spring.io/browse/INT-4498
* Use `FileCopyUtils` instead of `StreamUtils` in test-cases when we deal
with `InputStream` s and files resources.
* Fix reflection-based tests with AOP to use an `ArrayList` access
instead of `LinkedList` since an optimization in SF:
6d6aa72e8f
**Cherry-pick to 5.0.x and 4.3.x**
(cherry picked from commit a1f016a)
JIRA: https://jira.spring.io/browse/INT-4489
Make `MessageHistoryConfigurer` as a `BeanPostProcessor` and apply
tracking logic to processed beans if it is already started.
**Cherry-pick to 5.0.x**
Deprecated in favor of default methods on `ChannelInterceptor`.
* Fix race in RouterConcurrencyTest; no assertion on executor shutdown; increase time.
# Conflicts:
# spring-integration-amqp/src/test/java/org/springframework/integration/amqp/config/AmqpChannelParserTests.java
JIRA: https://jira.spring.io/browse/INT-4485
The `IntegrationFlowBeanPostProcessor` performs extra bean registration
for the `IntegrationComponentSpec.get()` result.
Essentially it is going to be the same object in the end, but during
bean registration phase we end up with names conflict.
* Remove an explicit `registerComponent()` for the
`IntegrationComponentSpec.get()`
* Modify `CorrelationHandlerTests` for all possible usage for the
`MessageChannelSpec`, which is essentially a `FactoryBean`
**Cherry-pick to 5.0.x**
JIRA: https://jira.spring.io/browse/INT-4486
The `SmartLifecycle.stop(Runnable callback)` must always call the
`callback` in the end independently of the internal state
* Revise all the `SmartLifecycle` implementations for the proper
`callback` handling
**Cherry-pick to 5.0.x and 4.3.x**
JIRA: https://jira.spring.io/browse/INT-4482
The outer try/catch sends an `ErrorMessage` for all exceptions; it should
only do so for `MessageConversionException`. Integration flow exceptions
will have been already handled by `MessageProducerSupport`.
Also, populate the raw message header consistently - previously it only
was populated for flow exceptions. Although the LEFE contains the raw
message, it should be in the `ErrorMessage` header for consistency.
**cherry-pick to 5.0.x, 4.3.x**
* Polishing - PR Comments
https://build.spring.io/browse/INT-MASTER-1058/
When we destroy manually registered `IntegrationFlow`, we need to
count with sub-flows and iterate all the dependant beans recursively
for full flow removal
**Cherry-pick to 5.0.x**
* INT-4471: PubSubChannel: Add errorHandler warn
JIRA: https://jira.spring.io/browse/INT-4471
* When an `Executor` is not provided, log warn that the provided
`ErrorHandler` is ignored.
**Cherry-pick to 5.0.x and 4.3.x**
* * Polish warn message
JIRA: https://jira.spring.io/browse/INT-4478
When we use a `GenericHandler` and an incoming payload is a `Map`, we
copy it into both arguments into the `Object` for the payload
and `Map` for the headers.
This way we lose headers in the target lambda
* Check a size of arguments on the target lambda and don't set a
payload into the `Map` argument if we have more than 1 arguments
**Cherry-pick to 5.0.x**
JIRA: https://jira.spring.io/browse/INT-4477
When running multiple roles, it is useful to be able to determine the
role for a particular context, e.g. in an event.
* Docs
**cherry-pick to 5.0.x**
(cherry picked from commit 73dbdb8)
* Fix LockRegLeaderIn for interrupted Thread.sleep
https://build.spring.io/browse/INT-FATS5IC-517
If current thread is interrupted, the `Thread.sleep()` interrupts
immediately.
In the catch block of the main loop in the `LockRegistryLeaderInitiator`
we have such a dangerous `sleep()` and don't restart election in this
candidate any more
* Move `Thread.sleep()` to else after checking the current thread for
interrupted state
* Remove `LongRunningIntegrationTest` rule from the
`RedisLockRegistryLeaderInitiatorTests` since it now works much faster
after proper `busy-wait` handling
**Cherry-pick to master**
* Ignore interruption on the sleep i catch and move on with loop
JIRA: https://jira.spring.io/browse/INT-4473
Previously, dynamic registration of integration flows with components configured
with the same `id` would fail with duplicate bean names.
Add `useFlowIdAsPrefix()` to the registration builder to enable the option.
Then, in the BPP, check the flag before naming the beans.
**cherry-pick to 5.0.x**
* Polishing according PR comments
* Widen `flowNamePrefix` responsibility in the
`IntegrationFlowBeanPostProcessor` since we may have many other
components in the dynamic flow with the same id, not only consumer
endpoints
# Conflicts:
# spring-integration-core/src/main/java/org/springframework/integration/config/dsl/IntegrationFlowBeanPostProcessor.java
# spring-integration-core/src/main/java/org/springframework/integration/dsl/context/IntegrationFlowContext.java
# spring-integration-core/src/main/java/org/springframework/integration/dsl/context/StandardIntegrationFlowContext.java
# src/reference/asciidoc/dsl.adoc
When we register `IntegrationFlow` s concurrently at runtime, we may
end up with the problem when we register the same object with the same
bean name, but in different places.
Or when we turn off bean overriding, we end up with the exception that
bean with the name already registered
* Wrap `IntegrationFlow` bean registration in the
`StandardIntegrationFlowContext` into the `Lock` when its bean name
is generating
* Make `StandardIntegrationFlowContext.registry` as `ConcurrentHashMap`
to avoid `ConcurrentModificationException` during `put()` and `remove()`
* Fix concurrency for beans registration with the generation names in
the `IntegrationFlowBeanPostProcessor` using an `IntegrationFlow` id
as a prefix for uniqueness.
**Cherry-pick to 5.0.x**
Fix generated bean name in the WebFluxDslTests
Use only single `Lock` in the `StandardIntegrationFlowContext`:
we don't need a fully blown `LockRegistry` there anymore since we have
only one synchronization block there and it is always around the same
type
* Add `What's New` note, and mention changes in the `dsl.adoc`
Minor doc polishing.
# Conflicts:
# spring-integration-core/src/main/java/org/springframework/integration/dsl/context/StandardIntegrationFlowContext.java
# spring-integration-core/src/test/java/org/springframework/integration/dsl/manualflow/ManualFlowTests.java
# src/reference/asciidoc/dsl.adoc
# src/reference/asciidoc/whats-new.adoc
JIRA: https://jira.spring.io/browse/INT-4466
When we schedule group for force complete in the
`AbstractCorrelatingMessageHandler`, we don't track a group `timestamp`
and its `lastModified` before the scheduled task.
This way, in the cluster environment, we may schedule several tasks
for different messages and the first started may release the group too
early.
Just because we extract a `MessageGroup` from the store already in the
task per se.
* Propagate the actual `timestamp` and `lastModified` from group before
scheduling task.
Compare these value with the actual group metadata in the
`processForceRelease()` before performing real `forceRelease()`.
This way we restore behavior before fixing memory leak, when we
propagated full `MessageGroup` to the scheduled task
* Implement `ResequencingMessageHandler.getComponentType()` for
consistency
* Remove unnecessary overhead with the `volatile` on many
`AbstractCorrelatingMessageHandler` properties, which hardly ever can be
changed at runtime
**Cherry-pick to 5.0.x and 4.3.x**
JIRA: https://jira.spring.io/browse/INT-4467
The package tangles is caused by the explicit classes declarations.
* Since we use only method definitions from those classes, there is just
enough to use class names and use reflection to get class objects and
then get methods from them
_The fix is fully compatible for back-porting_
**Cherry-pick to 5.0.x**