Commit Graph

2662 Commits

Author SHA1 Message Date
Artem Bilan
81f5b6bbbd Fix JacksonJsonUtils for Java 8 compatibility 2022-03-24 13:08:27 -04:00
Artem Bilan
eec3e956fe GH-3734: Support MessageHistory on Kafka deser
Fixes https://github.com/spring-projects/spring-integration/issues/3734

The `MessageHistory` is not in the trusted packages of the `DefaultKafkaHeaderMapper`
therefore it fails when `MessageHistory.read()` is performed.

* Configure default `DefaultKafkaHeaderMapper` in the `SubscribableKafkaChannel`,
`KafkaInboundGateway`, `KafkaMessageDrivenChannelAdapter` and `KafkaMessageSource`
to also trust packages exposed via `JacksonJsonUtils.DEFAULT_TRUSTED_PACKAGES`
which include a `MessageHistory`, too.

* Verify in some integration Kafka tests to be sure that `MessageHistory` is
deserialized properly in the transferred headers
* Rework some tests to use `@EmbeddedKafka` instead of `@BeforeAll/@AfterAll`

**Cherry-pick to `5.5.x`**
2022-03-22 16:02:08 -04:00
Artem Bilan
5e0e620351 Cancel subscription for MPS.subscribeToPublisher
The `Flux.takeWhile()` only works if there is data in the `Publisher`
to consume.
We still need to be able to cancel subscription and stop producing even if
there is no data at the moment.

* Change `takeWhile()` to the `doOnSubscribe()` and store `subscription`
in the `volatile` property of the `MessageProducerSupport`
* Cancel such a subscription in the `doStop()` impl
* Propagate `doStop()` to super in the `ZeroMqMessageProducer`
which is only one reactive channel adapter overriding `doStop()`
* Verify in the `ReactiveMessageProducerTests` that subscription is cancelled
for delayed data in the `Publisher`

**Cherry-pick to `5.5.x`**
2022-03-16 14:52:33 -04:00
Chris Bono
e80c0ab919 GH-3737: Add serialVersionUID to MessageHistory
Fixes https://github.com/spring-projects/spring-integration/issues/3737

* Add an explicit `serialVersionUID` to `MessageHistory` to avoid class version conflicts in the future.

See related GH issue for the workaround

**Cherry-pick to `5.5.x`**
2022-03-08 16:27:58 -05:00
Gary Russell
724f335750 Fix @Poller Javadoc
* Fix @Poller Javadoc - `receiveTimeout` was added as a property in 5.1.
* More javadoc polishing.

**cherry-pick to 5.5.x**
2022-02-03 15:30:34 -05:00
Artem Bilan
97a5ea4aca Move IntegrationDsl from .kt to .java
Turns out Eclipse Kotlin plugin is not perfect at the moment,
and it causes some code parsing problems in the editor.

* Move Kotlin annotation to Java to mitigate normal source code flow:
 Java to Kotlin, not opposite
2022-01-03 12:52:05 -05:00
Artem Bilan
5eb95f6cca More Kotlin DSL improvements 2022-01-03 09:49:22 -05:00
Artem Bilan
9759950d35 GH-3699: Fix typos in the IntegrationFlow javadoc
Fixes https://github.com/spring-projects/spring-integration/issues/3699
2021-12-22 10:16:07 -05:00
Artem Bilan
30622b285c Improve Kotlin DSL
* Add missed factories, introduced recently into Java DSL
* Add `@IntegrationDsl` - a Kotlin-specific `@DslMarker` annotation
to mark classes (including Java) which are used in Kotlin DSL as a builder pattern.
This way the scope of the builder is honored and IDE does not suggest functions from
higher lambda for builder
* Fix `element-list` reference for Dokka plugin configuration from the respective module
2021-12-21 17:21:31 -05:00
Artem Bilan
50fa345402 Fix new Sonar smell 2021-12-14 16:46:58 -05:00
Artem Bilan
2a3dac7ff3 GH-3694: Resolve circular dep in PublisherAnnBPP (#3695)
* GH-3694: Resolve circular dep in PublisherAnnBPP

Fixes https://github.com/spring-projects/spring-integration/issues/3694

* Move check for `PublisherAnnotationBeanPostProcessor` bean into the
`SmartInitializingSingleton.afterSingletonsInstantiated()` to break a circular dependency revealed
in the `InitializingBean.afterPropertiesSet()`

* * Fix unused import
2021-12-14 14:41:58 -05:00
Artem Bilan
8c85fc9957 Add MessageHandlerMethodFactoryCreatingFactoryBean
Rework the logic around `ManagedList` in the `DefaultConfiguringBeanFactoryPostProcessor`
when it registers a `IntegrationContextUtils.MESSAGE_HANDLER_FACTORY_BEAN_NAME` and
`IntegrationContextUtils.LIST_MESSAGE_HANDLER_FACTORY_BEAN_NAME` into a dedicated
`MessageHandlerMethodFactoryCreatingFactoryBean` with pure Java code instead of
`BeanDefinition` burden

* Deprecate `IntegrationContextUtils.DISPOSABLES_BEAN_NAME` constant for
already removed internal bean
* Align JVM args for Gradle with Java 17 on the `6.0` branch
2021-11-29 12:49:29 -05:00
Artem Bilan
a843dae151 Remove Disposables abstraction
* Remove `Disposables` since it is a package protected therefore could not be used outside
* Remove the logic relevant ot the `Disposables` in the `MessagingAnnotationPostProcessor` logic
* Replace a `registerSingleton()` and `initializeBean()` with the proper `registerBeanDefinition()`
and `getBean()` usage.
This way bean are going to be destroyed properly
* Remove `MessagingAnnotationPostProcessorChannelCreationTests` since its mocking logic is too vague
and really covered with many other real tests.
2021-11-22 14:29:43 -05:00
Artem Bilan
d7f925896f Check for Disposables bean before registration
The `MessagingAnnotationPostProcessor` registers a `Disposables` unconditionally.
The `afterPropertiesSet()` maybe called several times, so `IntegrationContextUtils.DISPOSABLES_BEAN_NAME`
registration has to be idempotent.

* Add `if (!this.beanFactory.containsBeanDefinition(IntegrationContextUtils.DISPOSABLES_BEAN_NAME))`
before trying to register `Disposables` bean
2021-11-22 10:20:34 -05:00
Artem Bilan
5452a6fbe6 Fix more Sonar smells 2021-11-11 12:20:25 -05:00
Artem Bilan
7f83f5f74a Revert AnnotationGatewayProxyFactoryBean logic
The `AnnotationGatewayProxyFactoryBean` can be configured via setters
and via annotation in the provided interface.

* Override `setProxyDefaultMethods()` to `true` only if annotation explicitly
provides `true`
2021-11-10 16:35:04 -05:00
Artem Bilan
a27b1ec28f Revert method references back to lambdas
Turns out Java does cast for the method reference argument before really calling
a delegating method.

* Revert cast method references (`((ApplicationContextAware) this.handler)::setApplicationContext`)
back to lambdas - `context -> ((ApplicationContextAware) this.handler).setApplicationContext(this.applicationContext)`
This way the cast is deferred until the lambda is called.
2021-11-10 16:03:50 -05:00
Artem Bilan
0aac4c0a86 Fix new Sonar smells 2021-11-10 14:55:48 -05:00
Artem Bilan
25100d1ac7 Fix unused import in the IntegrationRegistrar 2021-11-05 10:31:51 -04:00
Artem Bilan
a899b37ac3 DefaultConfiguringBFPP to BDRegistryPP
* Make a `DefaultConfiguringBeanFactoryPostProcessor` as a `BeanDefinitionRegistryPostProcessor`
to let it be processed properly in Spring AOT
* Register `DefaultConfiguringBeanFactoryPostProcessor` as a `BeanDefinition.ROLE_INFRASTRUCTURE`,
so it is removed in Spring AOT after processing and writing target bean definitions
2021-11-05 10:24:18 -04:00
Artem Bilan
d86647807e Use ReflectionUtils.makeAccessible() - not direct
The `LambdaMessageProcessor` and `MethodInvokingMessageSource`
 call `method.setAccessible(true)` unconditionally.

* Use `ReflectionUtils.makeAccessible()` for some optimization
* Remove `Content is not allowed in prolog` from the `JaxbMarshallingIntegrationTests`
since it is locale dependant and not relevant for the unit test logic
2021-11-03 10:54:24 -04:00
Artem Bilan
eb4d583a17 Add toReactivePublisher(autoStartOnSubscribe) (#3657)
* Add `toReactivePublisher(autoStartOnSubscribe)`

The `IntegrationFlowBuilder.toReactivePublisher()` returns a `Publisher<Message<?>>`
which may be subscribed somewhere late in the application logic, e.g.
when WebSocket (or RSocket) subscription is initiated by the external client.
In between application context startup and that subscription moment, the `IntegrationFlow`
must not try to produce messages since there is nothing to consumer them from the
`Publisher<Message<?>>` side.
One of the way is to have a source endpoint not started automatically and control its
lifecycle from the point fo reactive subscription

* Introduce an `IntegrationFlowBuilder.toReactivePublisher(boolean autoStartOnSubscribe)`
to let the framework do a job for an `IntegrationFlow` lifecycle control.
This way end-user doesn't need to know autowire a starting endpoint and use `doOnSubscribe()`
and similar callbacks
* Change `ConsumerEndpointFactoryBean` log message about a `FixedSubscriberChannel`
to `INFO` since an `autoStartup = false` really does not have any effect and there is nothing
for end-user to worry about.
The `IntegrationFlow` knows nothing about each endpoint internals and cannot control which
mark as `autoStartup = false` and which not

* Fix languge in JavaDocs

Co-authored-by: Gary Russell <grussell@vmware.com>

Co-authored-by: Gary Russell <grussell@vmware.com>
2021-11-01 16:49:59 -04:00
Artem Bilan
fc7d338302 GH-3656: Fix package tangles
Fixes https://github.com/spring-projects/spring-integration/issues/3656

* Move `JavaUtils` from `util` package to the root one to break any possible
tangling to/from other packages.
* Deprecate an existing `JavaUtils` for backward compatibility
* Remove `@IntegrationConverter` from the `JsonNodeWrapperToJsonNodeConverter`
and register it manually in the `ConverterRegistrar`.
The bean registration for the `JsonNodeWrapperToJsonNodeConverter` must be removed
in the next `6.0`
* Remove usage of `IntegrationContextUtils` from the `support` package
2021-11-01 15:06:01 -04:00
Artem Bilan
f520156053 GH-3653: Improve DSL parsing performance (#3654)
* GH-3653: Improve DSL parsing performance

Fixes https://github.com/spring-projects/spring-integration/issues/3653

* Refactor `IntegrationFlowBeanPostProcessor` to perform `beanFactory.getBeansOfType()`
as less as possible
* Implement a `NamedComponent` on the `StandardIntegrationFlow` for better
bean scanning performance in the `IntegrationFlowBeanPostProcessor`

* * Skip `NamedComponent` from bean scanning if `beanName == null`
2021-11-01 10:25:38 -04:00
Artem Bilan
ee8afc5b28 BeanDefinitions: Mix instanceSupplier and props 2021-10-22 15:17:46 -04:00
Gary Russell
e84bab6e0a GH-3648: Fix @Gateway.payloadExpression
Resolves https://github.com/spring-projects/spring-integration/issues/3648

When configuring a gateway proxy with XML, but specifying the payload expression
on the method `@Gateway` annotation, the expression was ignored, even though it
had been parsed.

`@Payload` worked.

With this change, if both `@Payload` and `@Gateway` are defined on a gateway method,
`@Gateway.payloadExpression` wins.

* Fix doc links.
2021-10-20 15:09:29 -04:00
Artem Bilan
d61df01acf Fix DSL sample in the doc
* Improve JavaDocs for `BaseIntegrationFlowDefinition` with renaming `payloadType`
param to `expectedType` since it can also be as a `Message.class`, not only type
for the payload.
* Add JavaDoc for `LambdaMessageProcessor` ctor
2021-10-19 14:19:58 -04:00
Artem Bilan
6c47593aef Fix ExpressionUtilsTests according SF changes
Related to: https://github.com/spring-projects/spring-framework/issues/27446
2021-10-19 09:46:35 -04:00
Artem Bilan
72b9e7001e GH-3643: Defer MeterRegistry bean dependency
Fixes https://github.com/spring-projects/spring-integration/issues/3643

The `ImportBeanDefinitionRegistrar` register its bean definition in the early phase.
It causes a problem with Spring Boot when an explicit `@EnableIntegrationManagement`
is declared: the `MeterRegistry` is provided later on via auto-configuration
and `MicrometerMetricsCaptor` has no knowledge about `MeterRegistry` at the
`ImportBeanDefinitionRegistrar` phase.

* Reworks `MicrometerMetricsCaptorRegistrar` to the `MicrometerMetricsCaptorConfiguration`
and use special conditional `MicrometerMetricsCaptorImportSelector` for that
`@EnableIntegrationManagement`.
This way a `MicrometerMetricsCaptor` `@Bean` consults `ObjectProvider<MeterRegistry>`
on its creating time and returns `null` if no `MeterRegistry` beans at all.
2021-10-18 17:15:45 -04:00
Artem Bilan
fe57fd281c Checkstyle changes
* Upgrade to Checkstyle 9.0
* apply some JavaDocs rules
* Fix JavaDocs rules violations
* Some other minor clean up in the affected classes
2021-09-28 11:55:25 -04:00
Artem Bilan
b92d52fe74 Improve docs for global default poller
* Fix Kotlin deprecation warning in the test
* Replace wrong `IntervalTrigger` mentioning in the docs to the proper `PeriodicTrigger`
* Fix code snippet in the `channel-adapter.adoc`
2021-09-20 10:35:16 -04:00
Artem Bilan
0fb64f1762 Upgrade to Kotlin 1.5
* To align with the rest of Spring portfolio, based on Spring Framework 5.3.x generation,
it is better to upgrade to the Kotlin version supported by SF
* Fix  `ClassUtils.isLambda()` to treat `$inlined$` classes as Kotlin lambdas and let
Java DSL to delegate to the `LambdaMessageProcessor` for better expected type handling.
Looks like Kotlin does not carry type info in its lambdas anymore (at least for functions).
* Add `-parameters` to the compiler args for possible method argument names discovery.
Essentially realign with the rest of portfolio
* Fix Kotlin tests for deprecated API
2021-09-13 16:46:05 -04:00
Artem Bilan
0f2285d5a3 Fix reply producing to not block reactive thread
When `DirectChannel` is used for reply producing, the data is
handled on the same thread which has produced it (normally), so
if we have a request-reply afterwards (e.g. `gateway()`), this thread
is blocked waiting for reply.
When the thread is assumed to be non-blocked (e.g. Netty event loop),
the request-reply withing such a thread for the same non-blocking client
causes a deadlock: the thread waits for reply, but at the same time it
supposes to fulfil a synchronization barrier with that reply

* Fix `AbstractMessageProducingHandler.asyncNonReactiveReply()` to use
a `publishOn(Schedulers.boundedElastic())` for reply `Mono` to free
producing thread from potential downstream blocking
* Demonstrate deadlock with a new test in the `RSocketDslTests`;
the original report was against WebFlux, but conditions are really
the same: `reactor-netty` is used as a low-level client

**Cherry-pick to `5.4.x`**
2021-09-13 10:42:04 -04:00
Artem Bilan
4456caffa1 Introduce high-level API for flows composition (#3624)
* Introduce high-level API for flows composition

For better end-user experience and more smooth integration logic
decomposition and distribution introduce an `IntegrationFlows.from(IntegrationFlow)`
to let to start the current flow from existing one.
On the other hand introduce an `BaseIntegrationFlowDefinition.to(IntegrationFlow)`
to let to continue the flow logic in the other existing one.
This way we can extract some templating logic into separate `IntegrationFlow` definitions
allowing at the same time to decompose a complex flow definition into logical reusable parts

* * Add more tests

* * Fix Checkstyle violation
* Add `@SuppressWarnings("overloads")` to new `from(IntegrationFlow)` and existing `from(Publisher)`.
Technically it does not make sense since `PublisherIntegrationFlow` is not a `public` class

* * Add docs
* Fix language in JavaDocs according review

* Fix language in the docs after review

Co-authored-by: Gary Russell <grussell@vmware.com>

Co-authored-by: Gary Russell <grussell@vmware.com>
2021-09-08 17:14:29 -04:00
Artem Bilan
024ffd1423 Fix generics for customizeMonoReply()
Related to: https://stackoverflow.com/questions/68637283/how-to-customize-response-in-spring-integration-using-webflux-when-a-specific-er

The function provided for the `ConsumerEndpointSpec.customizeMonoReply()` may convert
incoming value to something else.
With wildcards it cannot be compiled without casting.

* Add `<T, V>` generic arg for the `customizeMonoReply()` to conform in and out types carrying.
* Modify `WebFluxDslTests` to demonstrate the problem and confirm the fix

**Cherry-pick to `5.4.x` & `5.3.x`**
2021-08-09 15:12:10 -04:00
trungPa
9e512186ed GH-3549: Fix minor SonarQube smells
Fixes https://github.com/spring-projects/spring-integration/issues/3549
2021-07-23 11:07:39 -04:00
Artem Bilan
5ec8913d27 Fix pattern how Lock.unlock() is used
Related to https://build.spring.io/browse/INT-MAIN-84/

The `lock.unlock()` must be called in the `finally` block of the
nested `try..catch`, not in the outer which may just fail on `lock.lockInterruptibly()`
in which case there is just not going to be anything we can `unlock()` in the end

**Cherry-pick to `5.4.x` & `5.3.x`**
2021-07-19 17:07:54 -04:00
Artem Bilan
af9e69c251 Make MessageHistory JSON-serializable
* Add `org.springframework.integration.history` to trusted default packaged of the `JacksonJsonUtils`
* Add `@JsonCreator` to `MessageHistory` `private` ctor to let it to be created automatically by Jackson
* Add `equals()` and `hashCode()` into `MessageHistory` for the proper `Message` comparison
* Add  `MessageHistory` into headers for testing with Redis JSON (de)serialization

**Cherry-pick to `5.4.x` & `5.3.x`**
2021-07-19 12:37:05 -04:00
trungPa
9c718c37a6 GH-3424: Refactor to use logging methods from LogAccessor
Fixes https://github.com/spring-projects/spring-integration/issues/3424

* Use `LogMessage.format()` for lazily formatting

* Fix some logging statements in `JdbcChannelMessageStore`
2021-07-19 11:30:01 -04:00
Artem Bilan
ca9c9192c7 Fix new sonar smell
The `GatewayMethodMetadata.headerExpressions` is never `null`
2021-07-08 14:11:22 -04:00
Artem Bilan
4b83241e90 Fix new Sonar smells 2021-07-08 12:24:28 -04:00
Artem Bilan
a5776524e2 Fix SourcePollingChAdFB autoStartup propagation
The `spring.integration.properties` can come with the `noAutoStartup`
property where we can specify a source polling channel adapter endpoint to
not start automatically.
Turns out the `SourcePollingChannelAdapterFactoryBean` propagates its
`autoStartup` property unconditionally which will skip the `noAutoStartup` value
because an `AbstractEndpoint.setAutoStartup()` sets an `autoStartupSetExplicitly` state

* Fix `SourcePollingChannelAdapterFactoryBean` to rely on a `Boolean` object state
and don't call target endpoint `setAutoStartup()` if it was not set
* Adjust `spring.integration.properties` in tests to use `noAutoStartup`
for some `SourcePollingChannelAdapterFactoryBean`
* Verify that property was applied in the `IntegrationFlowTests.testWithSupplierMessageSourceImpliedPoller()`

**Cherry-pick to `5.4.x` & `5.3.x`**
2021-07-07 13:47:50 -04:00
Artem Bilan
db4f120dac Functional gateway bean definitions
* Rework `MessagingGatewayRegistrar` to parse messaging gateway annotation
an `<gateway>` XML using a supplier variant for bean definition.
Such a feature is required by Spring Native - otherwise we would need to
register reflection info for to many internal Spring Integration classes
* Such a change should benefit from regular JDK perspective, too -
we don't do reflection for this kind of bean registrations
2021-07-06 12:58:09 -04:00
Artem Bilan
1ac163330e Remove unused imports
**Cherry-pick to `5.4.x` & `5.3.x`**
2021-07-01 15:51:50 -04:00
Artem Bilan
b103752e68 Fix NPE for @Indexed in the MessagingGatewayReg
The `@Indexed` comes without any attributes, but it is included
into a chain via `importingClassMetadata.getMetaAnnotationTypes(ann)`.
So, skip attributes from meta annotation when it is `null`

**Cherry-pick to `5.4.x` & `5.3.x`**
2021-07-01 15:28:06 -04:00
Artem Bilan
3cf1d35d52 Fix CORS registration for IntGraphController
We fail with `NoClassDefFoundError` when we use `@EnableIntegrationGraphController`
in WebFlux env without Spring MVC.
Another issue that we don't register CORS for WebFlux

* Extract top-level package protected classes for MVC and WebFlux to register CORS
in the appropriate environment according classpath
* Adjust `HttpIntegrationConfigurationInitializer` and `WebFluxIntegrationConfigurationInitializer`
for native compatibility
* Add `@Indexed` for `@MessagingGateway` for indexer support in Spring Boot and Spring Native

**Cherry-pick to `5.4.x` & `5.3.x`**
2021-07-01 14:44:03 -04:00
KyeongMoon
8348b91ecc Fix typo in the InboundChannelAdapter JavaDocs 2021-06-15 09:33:03 -04:00
Artem Bilan
3ddaad9991 GH-3578: Fix JdbcMessageStore.getMessageGroup() (#3579)
Fixes https://github.com/spring-projects/spring-integration/issues/3578

The `JdbcTemplate.queryForMap()` extract values for columns to the closer target driver types.
For example H2 and Derby return `Long` for `BIGINT`.
Oracle for its `NUMBER(19,0)` returns `BigInteger`.
This makes the code in the `JdbcMessageStore.getMessageGroup()`
not platform independent.

* Fix `JdbcMessageStore` to map `ResultSet` to the `MessageGroupMetadata`
directly.
Mostly reinstating the previous behavior
* For that reason expose a default ctor for `MessageGroupMetadata`
and extract some setters to make code in the `JdbcMessageStore` more cleaner.
* This opens for us a possibility to implement a `MessageGroupStore.getGroupMetadata(groupId)`
for `JdbcMessageStore`
* Fix deprecation for `Flux.limitRequest()`
2021-06-10 15:54:40 -04:00
Artem Bilan
6b98192568 Increase timeout in fluky aggregator test
* Rework `DefaultMessageAggregatorIntegrationTests` to Junit 5
* Add `@DirtiesContext` to release a `TaskScheduler` resources
when the `ApplicationContext` is closed
2021-05-13 10:22:57 -04:00
Artem Bilan
e9f9119a49 Adjust timeouts in the PollingLifecycleTests
The `100` milliseconds are not enough to wait for thread barrier
on heavy-loaded environment like CI machine
2021-05-12 09:20:16 -04:00