Commit Graph

2953 Commits

Author SHA1 Message Date
Artem Bilan
ba57ee8a1b GH-9623: Fix ThreadStatePropagationChannelInterceptor for concurrency
Fixes: #9623
Issue link: https://github.com/spring-projects/spring-integration/issues/9623

The `ConcurrentModificationException` is thrown from the `ThreadStatePropagationChannelInterceptor.MessageWithThreadState.stateQueue`
which is a not thread-safe `LinkedList`

* Fix `ThreadStatePropagationChannelInterceptor.MessageWithThreadState.stateQueue` to be a `LinkedBlockingQueue` instead

**Auto-cherry-pick to `6.3.x` & `6.2.x`**
2024-10-31 13:23:44 -04:00
Artem Bilan
0d2595ef7c GH-9620: Use Locale.ROOT for neutral, case insensitive comparisons
Fixes: #9620
Issue link: https://github.com/spring-projects/spring-integration/issues/9620

**Auto-cherry-pick to `6.3.x` & `6.2.x`**
2024-10-31 10:59:05 -04:00
Artem Bilan
ff2b295be8 Fix version in ListenableFuture removal warning message 2024-10-30 16:28:26 -04: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
bd067da100 Fiux Checkstyle violation in the BaseMessageBuilder 2024-10-29 16:04: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
NaccOll
73bb813b53 GH-9561: Make DelayedMessageWrapper JSON-serializable
Fixes: #9561
PR: https://github.com/spring-projects/spring-integration/pull/9561

The `DelayHandler.DelayedMessageWrapper` cannot be deserialized when using `RedisMessageStore` and JSON serialization:
```
org.springframework.data.redis.serializer.SerializationException: Could not read JSON:Cannot construct instance of `org.springframework.integration.handler.DelayHandler$DelayedMessageWrapper` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: UNKNOWN; byte offset: #UNKNOWN]
	at org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer.deserialize(GenericJackson2JsonRedisSerializer.java:311)
```

* More code clean up and refactoring in the test

**Auto-cherry-pick to `6.3.x` & `6.2.x`**
2024-10-22 12:02:59 -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
NaccOll
4d08e11903 Add Redis lock periodic renewal
Although `RenewableLockRegistry` provides a renew interface, it is inconvenient for users.
Developers hope to have a lock that can be automatically renewed.
On the one hand, it can avoid subsequent failures caused by locks that will not expire when abnormal exits,
and on the other hand, it can avoid unlock failures caused by lock expired.

* Add `RenewableLockRegistry.setRenewalTaskScheduler()` and when it is set, schedule a `renew()` script periodically
when lock is acquired  from Redis with `1/3` of `expireAfter`
* Test and document the feature
2024-10-17 16:49:14 -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
2ed6d3e301 GH-9538: Rely on the customizeMonoReply() for thread switching
Fixes: https://github.com/spring-projects/spring-integration/issues/9538

Some applications might not be satisfied with `.publishOn(Schedulers.boundedElastic())`
used by default for `Mono` replies.

* Remove that `.publishOn(Schedulers.boundedElastic())` from the `AbstractMessageProducingHandler`.
Instead, the target project is free to make a choice via `customizeMonoReply()`, e.g.:
```
.handle(RSockets.outboundGateway("/lowercase")
										.clientRSocketConnector(this.clientRSocketConnector),
								endpoint -> endpoint.customizeMonoReply((message, mono) ->
										mono.publishOn(Schedulers.boundedElastic())))
```
2024-10-07 14:52:35 -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
ec31a5bed8 GH-9507: Migrate Python support to GraalVM Polyglot
Fixes: #9507
Issue link: https://github.com/spring-projects/spring-integration/issues/9507

* Deprecate `PythonScriptExecutor` in favor of `PolyglotScriptExecutor` with a `python` as language
* Add handling for `PolyglotWrapper` return type of the script evaluation
* Rework `DeriveLanguageFromExtensionTests.testParseLanguage()` to the `@ParameterizedTest`
2024-09-24 17:19:43 -04:00
Artem Bilan
8082f3c3f9 Fix some compiler smells for Java 21 2024-09-24 14:33:16 -04:00
Tran Ngoc Nhan
fc377126de Modernize code for diamond, isEmpty & pattern matching 2024-09-23 14:42:38 -04:00
Artem Bilan
a8174d5bce GH-9478: Fix MessagingGatewaySupport.onInit() for calling super.onInit()
Fixes: #9478
Issue link: https://github.com/spring-projects/spring-integration/issues/9478

Any `MessagingGatewaySupport` implementation does not register itself into a `SmartLifecycleRoleController`
because they don't call  `super.onInit()` of the `AbstractEndpoint`

* Fix `MessagingGatewaySupport` for calling  `super.onInit()` from its `onInit()`
* Verify `SmartLifecycleRoleController` registration in the `KafkaInboundGatewayTests`
* Remove out of use XML `group-id` attribute from Kafka channel adapter
and move it to the `channel` XSD as the place where it is really used

**Auto-cherry-pick to `6.3.x` & `6.2.x`**
2024-09-17 12:16:31 -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
feef055a53 Use withAssignmentDisabled() for IntSimpEvalCtxFactoryBean
**Auto-cherry-pick to `6.3.x` & `6.2.x`**
2024-08-20 11:10:52 -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
9180240ae0 Mitigate some IntegrationMBeanExporter early BF access
* Fix typo in the `spring-integration.xsd`
2024-08-13 14:15:42 -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
Sanghyuk Jung
32f2668260 Remove duplicated "the" in Javadocs 2024-08-02 19:26:09 -04: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
0461167aba Fix concurrency for StandardIntegrationFlowContext
If we don't get access to `BeanFactory` in exclusive mode,
the `getBean(Class<?>)` may fail with a `BeanCurrentlyInCreationException`
when we register several `IntegrationFlow` instances in parallel
2024-07-12 12:41:13 -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
4e7caed979 Add comment why and how we handle Mono->CompletableFuture 2024-07-03 12:42:10 -04:00
Artem Bilan
4a77dbcc46 GH-9259: Fix Reactor context propagation on reactive reply (#9284)
Fixes: #9259

The `Mono.toFuture()` does not propagate context to thread locals of the `CompletableFuture` consumer.
See `MonoToCompletableFuture`

* Fix `AbstractMessageProducingHandler` to convert reply `Mono` to `CompletableFuture` manually.
Use `doOnEach()` and set thread locals from the Reactor context manually around `replyFuture.complete()/completeExceptionally()`
* Add respective unit test into `WebFluxObservationPropagationTests` to ensure that same trace is used in downstream endpoints after WebFlux client reply

**Auto-cherry-pick to `6.3.x` & `6.2.x`**
2024-06-28 14:01:46 -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
bdcb856a90 Revise subscribed state in the FluxMessageChannel
The `Sinks.Many<Boolean> subscribedSignal` is a bit of overhead in the logic.

* Use `Mono.fromCallable(this.sink::currentSubscriberCount)` instead for `delaySubscription()`
when we perform `subscribeTo(Publisher)`

**Auto-cherry-pick to `6.3.x` & `6.2.x`**
2024-06-25 14:47:12 -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
b29ff9a710 GH-9191: Support byte[] for headers in the MessageReceiverContext
Fixes: #9191

Not all inbound protocol handlers convert header from native representation.
Sometimes they just come in as `byte[]`.

* Fix `MessageReceiverContext` to support `byte[]` for headers used in the observation,
e.g. `B3-*`, `traceparent` etc.

**Auto-cherry-pick to `6.3.x` & `6.2.x`**
2024-06-07 09:59:49 -04:00
Artem Bilan
e9561b41f1 GH-9215: Honor back-pressure in FluxMessageChannel
Fixes: #9215

* Instead of `share()` use `publish(1).refCount()` to prefetch only item from upstream.
* Also remove `publishOn(this.scheduler)` for upstream publishers in favor of opt-in on the consumer side.

**Auto-cherry-pick to `6.3.x` & `6.2.x`**
2024-06-06 11:38:45 -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