Commit Graph

1792 Commits

Author SHA1 Message Date
Artem Bilan
8d7133429f GH-9863: Deprecate PollerMetadata.sendTimeout option
Fixes: #9863
Issue link: https://github.com/spring-projects/spring-integration/issues/9863

The `PollerMetadata.sendTimeout` has been migrated to the `SourcePollingChannelAdapter.setSendTimeout()` long time ago.
Right now this option is not propagated anywhere

* Introduce missed `SourcePollingChannelAdapterSpec.sendTimeout`
* Deprecate (for removal) `PollerMetadata.sendTimeout`
* Verify `SourcePollingChannelAdapterSpec.sendTimeout` option in the `ReactiveStreamsTests`

(cherry picked from commit 0af3b25cd6)
2025-02-26 21:19:47 +00:00
Artem Bilan
915f5ad17e GH-9825: DelayerEndpointSpec: Set TaskScheduler to the handler as well
Fixes: #9825
Issue link: https://github.com/spring-projects/spring-integration/issues/9825

The `DelayerEndpointSpec` extends `ConsumerEndpointSpec` which has a `taskScheduler()` option.
However this is set only to the endpoint for this `MessageHandler`.

* Override `taskScheduler()` method on the `DelayerEndpointSpec` to set
the provided `TaskScheduler` to the `DelayHandler` as well

(cherry picked from commit 12fee0a9fb)
2025-02-13 17:17:25 +00:00
Artem Bilan
4d84220dad GH-9709: Fix IntegrationFlow for input channel resolution
Fixes: #9709
Issue link: https://github.com/spring-projects/spring-integration/issues/9709

The Java DSL loses an `inputChannel` when existing channel is referenced by its name.
Then the target IntegrationFlow does not contain a bean reference for this channel and when we call its `getInputChannel()` we got something from middle of the flow.
However, that `inputChannel` is really expected to be an input for the flow.

* Fix `IntegrationFlowBeanPostProcessor` to get a bean by `MessageChannelReference` and populate it into `targetIntegrationComponents`
as we do for newly created `DirectChannel` if there is no bean for provided `MessageChannelReference`

**Auto-cherry-pick to `6.3.x`**
2024-12-10 16:38:07 -05:00
Artem Bilan
5313c42e17 Some SimpleMessageGroupTests.testPerformance() optimization 2024-12-06 09:27:02 -05:00
Artem Bilan
da58fef3e0 More @DirtiesContext for tests in core module 2024-11-22 11:49:54 -05:00
Artem Bilan
8f4c2be0cb More @DirtiesContext for tests in core module
Additional code style cleanups in the affected classes

**Auto-cherry-pick to `6.3.x` & `6.2.x`**
2024-11-15 13:40:29 -05:00
Artem Bilan
09750f2012 Remove unnecessary Thread.sleep() from the AsyncGatewayTests
Such a `Thread.sleep()` makes tests slower, plus may cause a longer timing issue on slow CI/CD when CPU resources are limited

**Auto-cherry-pick to `6.3.x` & `6.2.x`**
2024-11-14 14:49:52 -05:00
Artem Bilan
4ccec0bae3 More @DirtiesContext in test of core module
The another attempt to mitigate out of memory error on GitHub Actions
2024-11-12 15:52:52 -05:00
Artem Bilan
a171ffd12d The EmbeddedJsonHeadersMessageMapper cleanups 2024-11-12 14:32:24 -05:00
Artem Bilan
b50c40279a GH-9617: @SuppressWarnings("removal") for ListenableFuture
Fixes: #9617
Issue link: https://github.com/spring-projects/spring-integration/issues/9617

The `ListenableFuture` is marked `forRemoval` in Spring Framework.
So, fix the code base to use `@SuppressWarnings("removal")`.
Also, add a warning into logs that `ListenableFuture` support will be removed in `7.0`.

* Fix JavaDocs where `ListenableFuture` is mentioned in favor of `CompletableFuture`
2024-10-30 15:24:10 -04:00
Artem Bilan
8dad15bac2 GH-9614: SimpleJsonSerializer: escape only \
Fixes: #9614
Issue link: https://github.com/spring-projects/spring-integration/issues/9614

The `Matcher.quoteReplacement()` escapes `\` as well as `$`.
However, Jackson tries to resolve special symbol from the escaped `$` and fails as `Unrecognized character escape '$' (code 36)`

* Fix `SimpleJsonSerializer.toElement()` to escape only `\`

**Auto-cherry-pick to `6.3.x` & `6.2.x`**
2024-10-30 14:17:41 -04:00
Artem Bilan
745dde1f65 Fiux Checkstyle violation in the MessageBuilderTests 2024-10-29 16:14:16 -04:00
Artem Bilan
f87aff3aa8 GH-9416: Extract BaseMessageBuilder for easier message extensions
Fixes: #9416
Issue link: https://github.com/spring-projects/spring-integration/issues/9416

The `MessageBuilderFactory` bean could be used a central place to provide custom `Message`
implementation into the application.
For example, the `GenericMessage.toString()` can be overridden to remove or mask sensitive
information from the payload or headers.

* Extract a `BaseMessageBuilder` from the `MessageBuilder` class to simplify
a custom `MessageBuilderFactory` implementation
* Test and document new feature and its purpose
2024-10-29 15:40:39 -04:00
Artem Bilan
e1cebafa5c GH-9558: Expose BarrierSpec.discardChannel & triggerTimeout
Fixes: #9558
Issue link: https://github.com/spring-projects/spring-integration/issues/9558

**Auto-cherry-pick to `6.3.x` & `6.2.x`**
2024-10-18 16:06:06 -04:00
Artem Bilan
15e914b75b Remove Bamboo mentioning from the tests 2024-10-18 14:33:43 -04:00
Artem Bilan
d5ab03c0c7 GH-9524: Expose SourcePollingChannelAdapterSpec.taskScheduler
Fixes: #9524
Issue link: https://github.com/spring-projects/spring-integration/issues/9524

It is useful in some use-cases to be able to inject a custom `TaskScheduler`
(e.g. with a `TaskDecorator`) into a source polling channel adapter.

* Add `SourcePollingChannelAdapterFactoryBean.setTaskScheduler()`
 and call it from the `SourcePollingChannelAdapterSpec.taskScheduler()`
* Fix JavaDocs typos in the `ConsumerEndpointSpec`
* Test custom `TaskScheduler` usage and mention new option in the `whats-new.adoc`
2024-10-14 17:22:29 -04:00
Artem Bilan
01c04fb87c Increase timeout in the MethodInvokingMessageHandlerTests
**Auto-cherry-pick to `6.3.x` & `6.2.x`**
2024-10-09 16:27:33 -04:00
Artem Bilan
2cf2f109f9 Revert "GH-9455: Introduce IntegrationKeepAlive (#9493)"
This reverts commit 8f838d04ce.
2024-09-30 13:34:07 -04:00
Artem Bilan
cdcffd7312 GH-9521: Make middle-flow endpoints started later
Fixes: https://github.com/spring-projects/spring-integration/issues/9521
2024-09-30 11:39:37 -04:00
Artem Bilan
90f06b1f76 Fix AsyncMessagingTemplateTests for time race condition 2024-09-30 09:10:18 -04:00
Artem Bilan
8f838d04ce GH-9455: Introduce IntegrationKeepAlive (#9493)
Fixes: #9455
Issue link: https://github.com/spring-projects/spring-integration/issues/9455

* Add an `IntegrationKeepAlive` infrastructure bean to initiate a long-lived non-daemon thread
to keep application alive when it cannot be kept like that for various reason, but has to.
* Expose `spring.integration.keepAlive` global property to disable an `IntegrationKeepAlive` auto-startup
* Test and document the feature
2024-09-25 14:31:41 -04:00
Artem Bilan
77ebee6d33 Fix Checkstyle violation 2024-09-24 17:25:52 -04:00
Artem Bilan
8082f3c3f9 Fix some compiler smells for Java 21 2024-09-24 14:33:16 -04:00
Artem Bilan
e3a46ca528 GH-9436: Add support for SpEL IndexAccessor configuration (#9451)
Fixes: #9436
Issue link: https://github.com/spring-projects/spring-integration/issues/9436

* Expose `IndexAccessor` configuration options on the `AbstractEvaluationContextFactoryBean`
and `SpelPropertyAccessorRegistrar`
* Expose `<index-accessors>` sub-element for the `<spel-property-accessors>`
* Adjust tests
* Document the feature, including recently added `JsonIndexAccessor`
2024-09-12 15:38:58 -04:00
Artem Bilan
775bfd6168 GH-9442: Register dynamic flows as singletons
Fixes: #9442
Issue link: https://github.com/spring-projects/spring-integration/issues/9442

When we register a `BeanDefinition`, its metadata is cached in the `DefaultListableBeanFactory.mergedBeanDefinitionHolders`
and it is not removed when we destroy bean.
This causes a memory leak with dynamic integration flows where even we destroy beans, their metadata is still cached.
This has more serious impact when random ids are used for dynamic integration flows.

* Rework `IntegrationFlowContext` logic to register singletons instead of `BeanDefinition`
* Adjust `IntegrationFlowBeanPostProcessor` logic to register singletons or `BeanDefinition`
according to the presence of `BeanDefinition` of the `IntegrationFlow` we are processing
* Introduce `ComponentSourceAware` to mimic a `BeanDefinition` metadata logic for bean source and its description.
This info helps a lot with exceptions where class in the `IntegrationFlow` might be fully from a Spring Integration package.
So, to give a clue what end-user code is related to the exception,
such a `ComponentSourceAware` is there to preserver and transfer "bean source"
* Implement `ComponentSourceAware` in the `IntegrationObjectSupport` since this is a central
place where we generate info for the Spring Integration exceptions
* Implement `ComponentSourceAware` in the `StandardIntegrationFlow` to propagate bean source info
down to its components for the mentioned `IntegrationObjectSupport` logic
* Introduce inner `StandardIntegrationFlowContext.IntegrationFlowComponentSourceAwareAdapter`
to be able to transfer "bean source" info from builder down to the target `IntegrationFlow` bean
2024-09-10 20:48:17 -04:00
Sam Brannen
49a0aaa793 GH-9383: Introduce JsonIndexAccessor
Fixes: #9383

Issue link: https://github.com/spring-projects/spring-integration/issues/9383

* Polish `JsonPropertyAccessor[Tests]`
* Introduce `JsonIndexAccessor`

This commit introduces a `JsonIndexAccessor` as a complement to the
existing `JsonPropertyAccessor`.

When a `JsonIndexAccessor` is registered with the SpEL `EvaluationContext`,
JSON arrays can be consistently indexed via integer literals (e.g.,[1]) instead of string literals representing integers (e.g., ['1']).
2024-09-04 10:25:46 -04:00
Artem Bilan
b5ec098eb5 More @DirtiesContext for tests in core
An attempt to mitigate a memory impact on limited CI/CD runners

**Auto-cherry-pick to `6.3.x` & `6.2.x`**
2024-08-13 16:33:47 -04:00
Artem Bilan
fdac8f1634 Fix tests for executorService.shutdown()
Even if `Executors.newSingleThreadExecutor()` returns a `FinalizableDelegatedExecutorService`,
an instance is kept in the memory until JVM exists.
That may lead to memory leak since we have a lot of threads in memory.

**Auto-cherry-pick to `6.3.x` & `6.2.x`**
2024-08-13 15:57:25 -04:00
Artem Bilan
4d787554b8 GH-9381: Introduce Control Bus commands management
Fixes: #9381

Currently, there is no way to know in one place what Control Bus commands are available and with what arguments

* Add `ControlBusCommandRegistry` infrastructure bean to gather control bus commands from beans and expose them for invocation
* Add `ControlBusController` to expose a `/control-bus` REST service against the mentioned `ControlBusCommandRegistry`
* Add `@EnableIntegrationManagement(loadControlBusCommands)` to be able to load all the Control Bus commands from the application context instead of on demand by default
* Deprecated existing SpEL(and Groovy)-based Control Bus functionality in favor of new, more manageable, logic
2024-08-13 13:26:27 -04:00
Mitchell
02b58277f4 GH-9369: Fix MutableMessageHeaders for serialization
Fixes: #9369 

* Implement `MutableMessageHeaders.readResolve()` to reinstate the instance

**Auto-cherry-pick to `6.3.x` & `6.2.x`**
2024-08-08 17:16:49 +00:00
Artem Bilan
6054e8bc9f More test clean up to minimize memory
Probably `@DirtiesContext` would remove application contexts for the JUnit cache
2024-07-24 16:45:48 -04:00
Artem Bilan
777c84f603 An attempt to fix OOM in the RecipientListRouterParserTests
* Add `@DirtiesContext` to the `RecipientListRouterParserTests`
* Remove manual `context.start();` since it is started by the `@SpringJUnitConfig` anyway
2024-07-16 11:59:35 -04:00
Artem Bilan
b2a3d25ffd Migrate ReturnAddressTests to JUnit 5
Looks like `ApplicaitonContext.stop()` is note called on `close()`.
This might cause an `OutOfMemoryError` on the CI

* Use Spring context configuration for the test environment
2024-07-16 11:55:50 -04:00
Artem Bilan
e0472d887a GH-9335: Fix MicrometerNodeEnhancer for a primary MeterRegistry bean
Fixes: #9335

Spring Boot provides a `CompositeMeterRegistry` bean marked with a `@Primary`.
So, this one has to be autowired whenever we would like to deal with application
environment.
The `MicrometerNodeEnhancer` has a flaw to skip `MeterRegistry` injection if we have more than one `MeterRegistry` bean.

* Fix `MicrometerNodeEnhancer` logic to use `ObjectProvider.getIfUnique()` API
which is able to deal with the `primary` properly.
Otherwise, `null` as it was before

**Auto-cherry-pick to `6.3.x` & `6.2.x`**
2024-07-16 11:16:06 -04:00
Artem Bilan
1fe40cf2fe Fix failing tests according new changes in SF SpEL module
Related to: https://github.com/spring-projects/spring-framework/issues/33174
2024-07-10 17:43:48 -04:00
Artem Bilan
4108ea520e GH-9260: Fix IntegrationManagementConfiguration.obtainObservationPatterns() logic
Fixes: #9260

The current `IntegrationManagementConfiguration.obtainObservationPatterns()` is to always have an `*` as a first
pattern in the final result.
Because of `HashSet` natural order.
This would lead to ignore all the patterns, especially those with negation

* Fix `IntegrationManagementConfiguration.obtainObservationPatterns()` logic to ignore regular
patterns if `*` is present.
Optimization wise.
* Always put `*` into the end of final array let negative patterns to do their job
* Modify `IntegrationGraphServerTests` & `WebFluxObservationPropagationTests`
test configurations to ensure that `*` pattern does not have a precedence over negative patterns.

**Auto-cherry-pick to `6.3.x` & `6.2.x`**
2024-06-25 16:25:39 -04:00
Artem Bilan
a5c449580b Rethrow an exception in the ManualFlowTests.testConcurrentRegistration()
The test fails sometimes, but its exception in the executor is lost.
Rethrow `exceptionHappened` to be reported into logs
2024-06-24 12:13:03 -04:00
Artem Bilan
66ca557a54 Remove extra empty line in the IntegrationObservabilityZipkinTests
**Auto-cherry-pick to `6.3.x`**
2024-06-03 15:25:29 -04:00
Artem Bilan
b0cbacfafb GH-9198: Fix MessageChannel observation for ErrorMessage
Fixes: #9198

When observation is enabled on the `MessageChannel`, the message to send is converted to a `MutableMessage`.
In case of `ErrorMessage` this causes a loss of `originalMessage` and may lead to `ClassCastException`
in the target error handler.

* Check for `ErrorMessage` in the `AbstractMessageChannel.sendWithObservation()` and create a new one
as a copy of original request, but including observation headers before performing `sendInternal()`
* Modify `IntegrationObservabilityZipkinTests` to verify an observation with an `ErrorMessage` and its handler.

**Auto-cherry-pick to `6.3.x` & `6.2.x`**
2024-06-03 14:49:33 -04:00
Artem Bilan
8b2da4f996 Start version 6.4
* Move `whats-new` to `changes-6.2-6.3.adoc`
* Upgrade dependency to the latest (including Gradle)
* Move Spring dependencies to based on SF-6.2
* Fix some deprecations and incompatibility
2024-05-28 20:07:35 -04:00
Artem Bilan
7abf1a53a7 GH-9110: propagate Reactor context to ReactiveMessageHandler
Fixes: #9110

* Move context propagation utilities to the `IntegrationReactiveUtils`
* Capture context into message header in the `IntegrationReactiveUtils.adaptSubscribableChannelToPublisher()`
before `sink.tryEmitNext()`
* Restore the context from message header in the `flatMap()` for `ReactiveStreamsConsumer.reactiveMessageHandler`

**Auto-cherry-pick to `6.2.x`**
2024-05-03 16:57:21 -04:00
Artem Bilan
c155d5d418 Add EmptyLineSeparator Checkstyle rule
* Support "blank lines around" via `spring-framework.xml` IDEA config
* Fix all the Checkstyle violations
2024-03-27 16:54:25 -04:00
Artem Bilan
69332a135b Upgrade some deps to their major/minor versions
* Manage `com.google.protobuf` to generate classes from Protos on the fly
* Fix Jackson API usage after its upgrade
2024-03-18 17:52:42 -04:00
Artem Bilan
074d544e94 GH-9001: Revise Observation propagation over the channel
Fixes: #9001

The `ObservationPropagationChannelInterceptor` does not propagate an observation properly.
And it fully cannot when the message channel is persistent.

* Deprecate `ObservationPropagationChannelInterceptor` in favor of enabled observation on the channel
and target `MessageHandler` which is a consumer of this channel.
* Remove tests with an `ObservationPropagationChannelInterceptor`
* Mention a correct behavior in the `metrics.adoc` and `ObservationPropagationChannelInterceptor` Javadocs

**Auto-cherry-pick to `6.2.x`**
2024-03-18 16:19:00 -04:00
Artem Bilan
ffe3605c90 GH-8981: Add UnicastingDispatcher.failoverStrategy option
Fixes: #8981

Sometime the simple `boolean failover` on the `MessageChannel` (default `true`)
is not enough to be sure that we can dispatch to the next handler or not.
Such a decision can be made using `ErrorMessageExceptionTypeRouter`, but that would
require an overhaul for the whole integration flow

* Introduce a simple `Predicate<Exception> failoverStrategy` into `UnicastingDispatcher`
and all its `MessageChannel` implementation consumers to allow to make a decision about next failover
according to a thrown exception from the current `MessageHandler`
* Expose `failoverStrategy` on the `DirectChannel`, `ExecutorChannel` & `PartitionedChannel`,
and add it into respective Java DSL specs
* Fix involved tests to rely on the `failoverStrategy` property from now on
* Document the new feature
2024-03-12 18:16:02 -04:00
Artem Bilan
3849d6adde Fix Kotlin DSL inconsistency & ambiguity 2024-03-12 12:13:25 -04:00
Artem Bilan
2731e9411e GH-7925: Make message history header as mutable
Fixes: #7925

The `MessageHistory.write()` creates not only a new instance of the `MessageHistory`,
but also a new copy of the whole message.
This significantly impacts the performance when we have too many components to track

* Make `MessageHistory` as append-only container and create a new instance (plus message)
only on the first track when no prior history is present
* Change `WireTap`, `BroadcastingDispatcher`, `AbstractMessageRouter` and `AbstractMessageSplitter`
to use a new `AbstractIntegrationMessageBuilder.cloneMessageHistoryIfAny()` API for every branch a message
is produced.
Essentially, create a new message with copy of the message history to let that downstream sub-flow
have its own trace
* Modify failed unit tests for a new logic where message history header is not immutable anymore
* This also fixes an `AbstractMessageSplitter` for propagating its track into messages it emits

* * Do not clone message history header if only one consume in multi-publish
* Fix typos in docs
2024-03-05 15:05:34 -05:00
Artem Bilan
2b576c57d6 GH-8950: Fix PublisherIntegrationFlow for AbstractEndpoint
Fixes: #8950

The `IntegrationFlow.toReactivePublisher(true)` makes `PublisherIntegrationFlow`
to be stopped from the beginning and waiting for the `Publisher.subscribe()`.
However only `EndpointSpec` components are marked as `autoStartup(false)`.
The `MessageProducerSupport` is not included, therefore unexpected messages
are produced to the channel in the end of flow without subscribers.

* Check for `AbstractEndpoint` component type in the `PublisherIntegrationFlow`
and mark it as `setAutoStartup(false)`
* Ensure in a new `ReactiveStreamsTests.messageProducerIsNotStartedAutomatically()` test
that `MessageProducerSupport` is not started from the beginning,
but rather when we subscribe to the `Publisher` via `StepVerifier`

**Auto-cherry-pick to `6.2.x` & `6.1.x`**
2024-02-23 13:01:38 -05:00
Artem Bilan
a8ed1dd9aa Optimize BPPs as AopInfrastructureBean
There is no need to post-process the framework internal BPPs.
Therefore, mark `GatewayProxyInstantiationPostProcessor`, `GlobalChannelInterceptorProcessor`, `IntegrationFlowBeanPostProcessor`
and `BaseIntegrationFlowDefinition.ReplyProducerCleaner` as an `AopInfrastructureBean`.
This way they are not post-processed via AOP `BeanPostProcessor`

* Migrate `org.springframework.integration.aop` tests to JUnit 5
* Fix race condition in the `FluxMessageChannelTests.noMemoryLeakInFluxMessageChannelForVolatilePublishers()`
where `FluxMessageChannel.upstreamSubscriptions` is updated from a different thread

**Auto-cherry-pick to `6.2.x`**
2024-02-09 17:35:06 -05:00
Artem Bilan
34bdff04c4 GH-8893: ExpERHA: Copy headers into ErrorMessage
Fixes: #8893

Simplify the target flows logic for `ExpressionEvaluatingRequestHandlerAdvice.failureChannel`
when no exception is re-thrown and target flow would like to produce a reply.

Currently, there is need in extra logic like `.enrichHeaders(e -> e.replyChannelExpression("payload.failedMessage.headers[replyChannel]"))`

* Copy failed `Message` headers into an `ErrorMessage` before sending it into the `failureChannel` from the `ExpressionEvaluatingRequestHandlerAdvice`
2024-02-07 14:18:27 -05:00