- inconsistent use of internal `TimeUnit`
- `setPeriod()` applied the unit, but `getPeriod()` did not
This test failed...
```java
@Test
public void testTriggerConsistency() {
final DynamicPeriodicTrigger trigger = new DynamicPeriodicTrigger(10, TimeUnit.SECONDS);
trigger.setPeriod(trigger.getPeriod());
assertThat(trigger.getPeriod(), equalTo(10_000));
}
```
Change the trigger to use `Duration` and deprecate the other methods.
https://build.spring.io/browse/INT-MASTER-1165/
The test checks how much time have we spent for the process.
It's too hard to be precise in all the environment, especially on slow
CI servers
* Make some code style polishing in the `AggregatorTests`
https://build.spring.io/browse/INT-MASTERSPRING40-441
Even if we `stop()` a `SourcePollingChannelAdapter` that doesn't mean
that task-in-progress can't deliver its result to the source consumer.
* Wrap a list `add()` and iterator operations to avoid a
`ConcurrentModificationException`
* Add `@SuppressWarnings("serial")` for the `RequestMessageHolder`
* Use non-caching JMS CF for the Inbound endpoints in the `JmsTests`
* Make `AsyncGatewayTests extends ActiveMQMultiContextTests` to keep
embedded broker opened in between test methods
* Add Java DSL `.fluxTransform(Function)` operator
For better interoperability with Reactor `Flux` from the
end-user perspective introduce an operator which could
call a target `Function` with integration data wrapped to the `Flux`
and expect a `Publisher<?>` result to continue the flow.
This way end-user just needs to implement a `Function` (or method)
to accept the `Flux` as an input and return some `Publisher`
after the sequence of reactive operators.
Such a new operator also allows a smooth integration with the
Spring Cloud Function, where it is just enough to lookup the function
in the catalog and inject it into this operator
* * Move `fluxTransform()` body to `Transformers` for cleaner context
distribution
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**
* INT-4517: Refactor beans in IntegrationRegistrar
JIRA: https://jira.spring.io/browse/INT-4517
The `IntegrationRegistrar` populates beans into the application context
too early and when the `allowBeanDefinitionsOverride` is disabled we
end up with the `BeanDefinitionOverrideException` just because end-user
beans are applied later.
* Move most of the bean definitions which can be overridden in the target
application from the `IntegrationRegistrar` into the
`DefaultConfiguringBeanFactoryPostProcessor`
* Revise their registration logic to be sure that some of them are
registered only once in the parent context nad others are registered
in the child context as well
* Refactor a `DslIntegrationConfigurationInitializer` do not register
an `IntegrationFlowDefinition.ReplyProducerCleaner` in the child context
one more time: it doesn't bring any local store within the current
child context
* Introduce a `NoBeansOverrideAnnotationConfigContextLoader` in tests
to ensure that in some test-cases we disallow an
`allowBeanDefinitionsOverride` as it is now in Spring Boot since it is
enabled by default in the Spring Framework
* Revernt DslIntegrationConfigurationInitializer changes
Regsiter all the required infrastructure beans in all the application
contexts to avoid class loader issue for `static` store access
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**
* INT-4480: Use component type for ids in the flow
JIRA: https://jira.spring.io/browse/INT-4480
For better readability of bean names, e.g. from the metrics collectors,
generate them from the component type instead of their fully qualified
class names
* * Fix bean name for injection in the WebFluxDslTests
JIRA: https://jira.spring.io/browse/INT-4457
When an `IntegrationFlow` is reply-based (we expect a reply in the
beginning) and `log()` (or `wireTap()`) is used in the end, we are
forced to add an empty `bridge()` in the end to ensure a `replyChannel`
header routing
* Fix `IntegrationFlowDefinition` to add `enrichHeaders()` in the end
to populate a `nullChannel` as a `replyChannel` header if that is missed
in the request message headers.
This way we cover both use-cases when we expect reply from the flow and
when it is used as a one-way scenario
* Improve a `HeaderEnricher` do not create a new `Message` if there are
no new headers to add/remove
* Remove a note from the `dsl.adoc` about now redundant `bridge()` after
`log()`
* Resolve TODO in the `.handle()` paragraph
* Restore anonymous class in the MessageHistoryIntegrationTests:
Mockito can't mock/spy lambdas because they are `final` classes
* Introduce `IntegrationFlowDefinition.logAndReply()` operator
* Fix logging message
Doc Polishing
Packages with `@Nullable` annotations need to have `@NonNulApi` at the package level.
There may be classes in these packages that have nullable arguments/returns that are
not currently marked as `@Nullable`. These will be fixed over time.
Also suppress JSR305 warnings when compiling tests.
* Polishing - PR Comments
* 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**
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**
https://build.spring.io/browse/INT-MASTER-1134
According the latest released reactor-core-3.2.0.M2, there is no yet
a `.onErrorContinue()` operator.
We need to stick with the `.errorStrategyContinue()` for time being
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-4507
* Add `RedisUtils` with the `isUnlinkAvailable()` to check the Redis
server version to be sure that `UNLINK` is available or not
* Use `RedisUtils.isUnlinkAvailable()` in the `RedisMessageStore` and
`RedisLockRegistry` when a removal functionality is performed
* Add `AbstractKeyValueMessageStore.doRemoveAll(Collection<Object> ids)`
for optimization
* Implement `doRemoveAll()` in the `RedisMessageStore` and
`GemfireMessageStore`
**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**
* INT-4381: MessageSources refactoring
JIRA: https://jira.spring.io/browse/INT-4381
* Make all the out-of-the-box `MessageSource` implementations based
on the `AbstractMessageSource`
* Fix `JdbcPollingChannelAdapterIntegrationTests` for sporadic failure
because of `fixed-rate` for the poller
* Fix HeaderEnricherTests race condition
The `errorChannel()` expect an error in the `testErrorChannel` after
`1000` ms, but at the same time the `poller` in configured for the
`3000` ms.
* Increase all the timeouts for replies
* Decrease a `fixed-delay` on the `poller`
* Some other code style polishing for the `HeaderEnricherTests`
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**
JIRA: https://jira.spring.io/browse/INT-4488
Since `PublisherAnnotationBeanPostProcessor` is quite expensive
(1.5x the CPU used by `MessagingAnnotationPostProcessor` in a simple
application)
* So not register a `PublisherAnnotationBeanPostProcessor` by default.
The `@EnablePublisher` has to be presented on the `@Configuration`
to allow the `@Publisher` AOP
* Change the `<int:annotation-config>` to require a new
`<int:enable-publisher>` sub-element for similar purpose - do not
register `PublisherAnnotationBeanPostProcessor` by default
JIRA: https://jira.spring.io/browse/INT-4452
This is pretty typical in practice to get a `groupTimeout` to be
evaluated to a negative value: some business decisions, sensitive
calculations and so on.
* Treat any non-positive `groupTimeout` as a signal to expire group
immediately without scheduling.
Only `null` is considered as a signal do nothing for the current message
* Polishing for some tests for better performance - saves some execution
time
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**
JIRA: https://jira.spring.io/browse/INT-4487
Currently the `AbstractReplyProducingMessageHandler` applies advices
only in the `afterPropertiesSet()` phase.
When we use bean references for `MessageHandler`s in Java DSL, the
`.advice()` provided in the flow definition is not applied to the
`AbstractReplyProducingMessageHandler`.
* For consistency with the endpoint configured by the DSL definition,
override and reconfigure advices in the `AbstractReplyProducingMessageHandler`
bean reference during DSL parsing and processing.
Fix `TwitterSearchOutboundGatewayParserTests` for the proper assert
* Destroy RmiInboundGateway.RmiServiceExporter
The internal instance `RmiServiceExporter` of the `RmiInboundGateway`
has to be destroyed together with the outer instance to unbind `service`
from the RMI registry
* Perform some polishing for the `RmiInboundGateway` and optimize
a `AbstractInboundGatewayParser` for late channels binding
* * Polishing some tests
* Expose getters for channels on the `MessagingGatewaySupport`
* Fix RMI tests to use random port
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**
JIRA: https://jira.spring.io/browse/INT-4476
When mapping outbound headers, if the `AmqpHeaders` `ID` and `Timestamp` headers
are not present, fall back to mapping the `MessageHeaders` variants (if present).
Also fix some PDF overflows.
JIRA: https://jira.spring.io/browse/INT-4474
* Populate proper `Integer.MIN_VALUE` phase for non-`PollingConsumer`s
in the `ConsumerEndpointFactoryBean`
**Cherry-pick to 5.0.x and 4.3.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**
* 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