GH-8626: Provide cleaner transform() DSL (#8653)
* GH-8626: Provide cleaner `transform()` DSL Fixes https://github.com/spring-projects/spring-integration/issues/8626 * Add missed `transform(String beanName, @Nullable String methodName)` API * Introduce a `TransformerSpec` to expose a strict API to configure transformer variants. * Introduce `transformWith(Consumer<TransformerSpec>)` as a single point of all possible transformer and its endpoint options * Deprecate those `IntegrationFlowDefinition.transform()` variants which are harder to configure as several lambda arguments This change will make Kotlin & Groovy DSL more readable and straightforward * * Use new `transformWith()` in tests where a deprecated API still used * Add JavaDocs to `TransformerSpec` * Fix generic types for `BaseIntegrationFlowDefinition.transformWith()` - they make sense exactly on the `TransformerSpec.transformer()` only * Apply `transformWith()` for Groovy DSL * Introduce a new `ClassUtils.isLambda(Object candidate)` and add a check for Groovy `Closure` * Fix `GroovyIntegrationFlowDefinition.createConfigurerIfAny()` to propagate a `Consumer` argument down to the `Closure` * * Rename `TransformerSpec -> TransformerEndpointSpec` for better context meaning of the class * Introduce `KotlinTransformerEndpointSpec` as an extension of the `TransformerEndpointSpec` to have an `inline fun <reified P> transformer(crossinline function: (P) -> Any)` for Kotlin style * Add `KotlinIntegrationFlowDefinition.transformWith(KotlinTransformerEndpointSpec)` * Deprecate Kotlin methods which are covered by the mentioned `transformWith()` * Fix tests to use new API * Mentioned the change in the doc
This commit is contained in:
@@ -64,6 +64,7 @@ import org.springframework.integration.dsl.MessageChannels;
|
||||
import org.springframework.integration.dsl.PollerSpec;
|
||||
import org.springframework.integration.dsl.Pollers;
|
||||
import org.springframework.integration.dsl.QueueChannelSpec;
|
||||
import org.springframework.integration.dsl.TransformerEndpointSpec;
|
||||
import org.springframework.integration.dsl.Transformers;
|
||||
import org.springframework.integration.endpoint.AbstractEndpoint;
|
||||
import org.springframework.integration.endpoint.EventDrivenConsumer;
|
||||
@@ -671,17 +672,24 @@ public class IntegrationFlowTests {
|
||||
.fixedSubscriberChannel()
|
||||
.<String, Integer>transform(Integer::parseInt)
|
||||
.transform(Foo::new)
|
||||
.transform(new PayloadSerializingTransformer(),
|
||||
c -> c.autoStartup(false).id("payloadSerializingTransformer"))
|
||||
.transformWith(this::payloadSerializingTransformer)
|
||||
.channel(MessageChannels.queue(new SimpleMessageStore(), "fooQueue"))
|
||||
.transform(Transformers.deserializer(Foo.class.getName()))
|
||||
.<Foo, Integer>transform(f -> f.value)
|
||||
.filter("true", e -> e.id("expressionFilter"))
|
||||
.channel(publishSubscribeChannel())
|
||||
.transform((Integer p) -> p * 2, c -> c.advice(this.expressionAdvice()))
|
||||
.transformWith(t -> t
|
||||
.transformer((Integer p) -> p * 2)
|
||||
.advice(expressionAdvice()))
|
||||
.get();
|
||||
}
|
||||
|
||||
private void payloadSerializingTransformer(TransformerEndpointSpec spec) {
|
||||
spec.transformer(new PayloadSerializingTransformer())
|
||||
.autoStartup(false)
|
||||
.id("payloadSerializingTransformer");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MessageChannel publishSubscribeChannel() {
|
||||
return new PublishSubscribeChannel();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2022 the original author or authors.
|
||||
* Copyright 2016-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -190,7 +190,8 @@ public class ManualFlowTests {
|
||||
IntegrationFlow myFlow = f -> f
|
||||
.<String, String>transform(String::toUpperCase)
|
||||
.channel(MessageChannels.queue())
|
||||
.transform("Hello, "::concat, e -> e
|
||||
.transformWith(t -> t
|
||||
.transformer("Hello, "::concat)
|
||||
.poller(p -> p
|
||||
.fixedDelay(10)
|
||||
.maxMessagesPerPoll(1)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2022 the original author or authors.
|
||||
* Copyright 2016-2023 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -262,8 +262,10 @@ public class ReactiveStreamsTests {
|
||||
return IntegrationFlow
|
||||
.from("inputChannel")
|
||||
.split(s -> s.delimiters(","))
|
||||
.<String, Integer>transform(Integer::parseInt,
|
||||
e -> e.reactive(flux -> flux.publishOn(Schedulers.parallel())).id("reactiveTransformer"))
|
||||
.transformWith(t -> t
|
||||
.<String, Integer>transformer(Integer::parseInt)
|
||||
.reactive(flux -> flux.publishOn(Schedulers.parallel()))
|
||||
.id("reactiveTransformer"))
|
||||
.channel(MessageChannels.queue())
|
||||
.log()
|
||||
.toReactivePublisher();
|
||||
|
||||
@@ -460,10 +460,11 @@ public class TransformerTests {
|
||||
@Bean
|
||||
public IntegrationFlow transformFlowWithError() {
|
||||
return f -> f
|
||||
.transform(p -> {
|
||||
throw new RuntimeException("intentional");
|
||||
},
|
||||
e -> e.advice(expressionAdvice()))
|
||||
.transformWith((t) ->
|
||||
t.transformer(p -> {
|
||||
throw new RuntimeException("intentional");
|
||||
})
|
||||
.advice(expressionAdvice()))
|
||||
.log();
|
||||
}
|
||||
|
||||
|
||||
@@ -161,7 +161,10 @@ class KotlinDslTests {
|
||||
|
||||
val integrationFlow =
|
||||
integrationFlow(publisher) {
|
||||
transform<Message<Int>>({ it.payload * 2 }) { id("foo") }
|
||||
transformWith {
|
||||
transformer<Message<Int>> { it.payload * 2 }
|
||||
id("foo")
|
||||
}
|
||||
channel(fluxChannel)
|
||||
}
|
||||
|
||||
@@ -249,7 +252,10 @@ class KotlinDslTests {
|
||||
@Bean
|
||||
fun functionFlow() =
|
||||
integrationFlow<Function<ByteArray, String>>({ beanName("functionGateway") }) {
|
||||
transform(Transformers.objectToString()) { id("objectToStringTransformer") }
|
||||
transformWith {
|
||||
transformer(Transformers.objectToString())
|
||||
id("objectToStringTransformer")
|
||||
}
|
||||
transform<String> { it.uppercase() }
|
||||
split<Message<*>> { it.payload }
|
||||
split<String>({ it }) { id("splitterEndpoint") }
|
||||
@@ -292,7 +298,10 @@ class KotlinDslTests {
|
||||
fun fixedSubscriberFlow() =
|
||||
integrationFlow("fixedSubscriberInput", true) {
|
||||
log<Any>(LoggingHandler.Level.WARN) { it.payload }
|
||||
transform("payload") { id("spelTransformer") }
|
||||
transformWith {
|
||||
expression("payload")
|
||||
id("spelTransformer")
|
||||
}
|
||||
}
|
||||
|
||||
@Bean
|
||||
|
||||
Reference in New Issue
Block a user