Skip to content

Commit 83f2a9c

Browse files
Migrate Groovy DSL extension project (#3914)
* Migrate Groovy DSL extension project * Upgrade to Groovy `4.0.5` * Apply `groovy` plugin for Groovy module to be able to compile Groovy classes for DSL * Document new feature * * Restore `lambdaWrapper` for the `GroovyIntegrationFlowDefinition.handle()` to be able to preserve a generic argument type * * Migrate more Spock test methods to JUnit style * * Add missed `assert` to Groovy tests * Fix language in docs Co-authored-by: Gary Russell <[email protected]> * * Fix Copyright and `@since` in new classes * Remove deprecated `IntegrationFlows` class mentions in the `groovy-dsl.adoc` Co-authored-by: Gary Russell <[email protected]>
1 parent fe06fbc commit 83f2a9c

File tree

9 files changed

+2009
-7
lines changed

9 files changed

+2009
-7
lines changed

build.gradle

+10-6
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ ext {
6767
ftpServerVersion = '1.2.0'
6868
graalvmVersion = '22.2.0'
6969
greenmailVersion = '2.0.0-alpha-2'
70-
groovyVersion = '3.0.13'
70+
groovyVersion = '4.0.5'
7171
hamcrestVersion = '2.2'
7272
hazelcastVersion = '5.1.3'
7373
hibernateVersion = '6.1.3.Final'
@@ -167,6 +167,7 @@ allprojects {
167167
mavenBom "io.micrometer:micrometer-tracing-bom:$micrometerTracingVersion"
168168
mavenBom "org.apache.camel:camel-bom:$camelVersion"
169169
mavenBom "org.testcontainers:testcontainers-bom:$testcontainersVersion"
170+
mavenBom "org.apache.groovy:groovy-bom:$groovyVersion"
170171
}
171172

172173
}
@@ -617,14 +618,17 @@ project('spring-integration-graphql') {
617618

618619
project('spring-integration-groovy') {
619620
description = 'Spring Integration Groovy Support'
621+
622+
apply plugin: 'groovy'
623+
620624
dependencies {
621625
api project(':spring-integration-scripting')
622-
api "org.codehaus.groovy:groovy:$groovyVersion"
626+
api 'org.apache.groovy:groovy'
623627
api 'org.springframework:spring-context-support'
624628

625629
testImplementation 'org.springframework:spring-web'
626630

627-
testRuntimeOnly "org.codehaus.groovy:groovy-dateutil:$groovyVersion"
631+
testRuntimeOnly 'org.apache.groovy:groovy-dateutil'
628632
}
629633
}
630634

@@ -852,7 +856,7 @@ project('spring-integration-scripting') {
852856
providedImplementation "org.graalvm.sdk:graal-sdk:$graalvmVersion"
853857

854858
testImplementation "org.jruby:jruby-complete:$jrubyVersion"
855-
testImplementation "org.codehaus.groovy:groovy-jsr223:$groovyVersion"
859+
testImplementation 'org.apache.groovy:groovy-jsr223'
856860
testImplementation "org.python:jython-standalone:$jythonVersion"
857861

858862
testRuntimeOnly 'org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable'
@@ -1143,7 +1147,7 @@ task schemaZip(type: Zip) {
11431147
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
11441148

11451149
javaProjects.each { subproject ->
1146-
Properties schemas = new Properties();
1150+
Properties schemas = new Properties()
11471151
def shortName = subproject.name.replaceFirst("${rootProject.name}-", '')
11481152
if (subproject.name.endsWith('-core')) {
11491153
shortName = ''
@@ -1204,7 +1208,7 @@ task distZip(type: Zip, dependsOn: [docsZip, schemaZip]) {
12041208
description = "Builds -${archiveClassifier} archive, containing all jars and docs, " +
12051209
"suitable for community download page."
12061210

1207-
ext.baseDir = "${project.name}-${project.version}";
1211+
ext.baseDir = "${project.name}-${project.version}"
12081212

12091213
from('src/dist') {
12101214
include 'readme.txt'

spring-integration-groovy/src/main/groovy/org/springframework/integration/groovy/dsl/GroovyIntegrationFlowDefinition.groovy

+1,309
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
/*
2+
* Copyright 2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.integration.groovy.dsl
18+
19+
import groovy.transform.CompileStatic
20+
import groovy.transform.stc.ClosureParams
21+
import groovy.transform.stc.SimpleType
22+
import org.reactivestreams.Publisher
23+
import org.springframework.integration.core.MessageSource
24+
import org.springframework.integration.dsl.GatewayProxySpec
25+
import org.springframework.integration.dsl.IntegrationFlow
26+
import org.springframework.integration.dsl.IntegrationFlowBuilder
27+
import org.springframework.integration.dsl.IntegrationFlowDefinition
28+
import org.springframework.integration.dsl.MessageProducerSpec
29+
import org.springframework.integration.dsl.MessageSourceSpec
30+
import org.springframework.integration.dsl.MessagingGatewaySpec
31+
import org.springframework.integration.dsl.SourcePollingChannelAdapterSpec
32+
import org.springframework.integration.endpoint.MessageProducerSupport
33+
import org.springframework.integration.gateway.MessagingGatewaySupport
34+
import org.springframework.messaging.Message
35+
import org.springframework.messaging.MessageChannel
36+
37+
import java.util.function.Consumer
38+
import java.util.function.Supplier
39+
40+
/**
41+
* The factory class for Spring Integration Groovy DSL closures.
42+
*
43+
* @author Artem Bilan
44+
*
45+
* @since 6.0
46+
*/
47+
@CompileStatic
48+
class IntegrationGroovyDsl {
49+
50+
/**
51+
* Functional {@link IntegrationFlow} definition in Groovy DSL.
52+
* @param flow the {@link Closure} for {@link IntegrationFlowDefinition}
53+
*/
54+
static IntegrationFlow integrationFlow(
55+
@DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST)
56+
@ClosureParams(value = SimpleType,
57+
options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition')
58+
Closure<?> flow) {
59+
60+
{ IntegrationFlowDefinition flowDefinition ->
61+
def delegate = new GroovyIntegrationFlowDefinition(flowDefinition)
62+
flow.delegate = delegate
63+
flow.resolveStrategy = Closure.DELEGATE_FIRST
64+
flow(delegate)
65+
} as IntegrationFlow
66+
}
67+
68+
/**
69+
* Functional {@link IntegrationFlow} definition in Groovy DSL for
70+
* {@link IntegrationFlow#from(Class, Consumer)} factory method.
71+
*/
72+
static IntegrationFlow integrationFlow(
73+
Class<?> serviceInterface,
74+
@DelegatesTo(value = GatewayProxySpec, strategy = Closure.DELEGATE_FIRST)
75+
@ClosureParams(value = SimpleType,
76+
options = 'org.springframework.integration.dsl.GatewayProxySpec')
77+
Closure<?> gatewaySpec = null,
78+
@DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST)
79+
@ClosureParams(value = SimpleType,
80+
options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition')
81+
Closure<?> flow) {
82+
83+
Consumer<GatewayProxySpec> configurer = GroovyIntegrationFlowDefinition.createConfigurerIfAny(gatewaySpec)
84+
buildIntegrationFlow(IntegrationFlow.from(serviceInterface, configurer), flow)
85+
}
86+
87+
/**
88+
* Functional {@link IntegrationFlow} definition in Groovy DSL for
89+
* {@link IntegrationFlow#from(String, boolean)} factory method.
90+
*/
91+
static IntegrationFlow integrationFlow(
92+
String channelName,
93+
Boolean fixedSubscriber = false,
94+
@DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST)
95+
@ClosureParams(value = SimpleType,
96+
options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition')
97+
Closure<?> flow) {
98+
99+
buildIntegrationFlow(IntegrationFlow.from(channelName, fixedSubscriber), flow)
100+
}
101+
102+
/**
103+
* Functional {@link IntegrationFlow} definition in Groovy DSL for
104+
* {@link IntegrationFlow#from(MessageChannel)} factory method.
105+
*/
106+
static IntegrationFlow integrationFlow(
107+
MessageChannel channel,
108+
@DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST)
109+
@ClosureParams(value = SimpleType,
110+
options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition')
111+
Closure<?> flow) {
112+
113+
buildIntegrationFlow(IntegrationFlow.from(channel), flow)
114+
}
115+
116+
/**
117+
* Functional {@link IntegrationFlow} definition in Groovy DSL for
118+
* {@link IntegrationFlow#from(MessageSource, Consumer)} factory method.
119+
*/
120+
static IntegrationFlow integrationFlow(
121+
MessageSource<?> messageSource,
122+
@DelegatesTo(value = SourcePollingChannelAdapterSpec, strategy = Closure.DELEGATE_FIRST)
123+
@ClosureParams(value = SimpleType,
124+
options = "org.springframework.integration.dsl.SourcePollingChannelAdapterSpec")
125+
Closure<?> adapterSpec = null,
126+
@DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST)
127+
@ClosureParams(value = SimpleType,
128+
options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition')
129+
Closure<?> flow) {
130+
131+
Consumer<SourcePollingChannelAdapterSpec> configurer =
132+
GroovyIntegrationFlowDefinition.createConfigurerIfAny(adapterSpec)
133+
buildIntegrationFlow(IntegrationFlow.from(messageSource, configurer), flow)
134+
}
135+
136+
/**
137+
* Functional {@link IntegrationFlow} definition in Groovy DSL for
138+
* {@link IntegrationFlow#from(org.springframework.integration.dsl.MessageSourceSpec, Consumer)} factory method.
139+
*/
140+
static IntegrationFlow integrationFlow(
141+
MessageSourceSpec messageSourceSpec,
142+
@DelegatesTo(value = SourcePollingChannelAdapterSpec, strategy = Closure.DELEGATE_FIRST)
143+
@ClosureParams(value = SimpleType,
144+
options = "org.springframework.integration.dsl.SourcePollingChannelAdapterSpec")
145+
Closure<?> adapterSpec = null,
146+
@DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST)
147+
@ClosureParams(value = SimpleType,
148+
options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition')
149+
Closure<?> flow) {
150+
151+
Consumer<SourcePollingChannelAdapterSpec> configurer =
152+
GroovyIntegrationFlowDefinition.createConfigurerIfAny(adapterSpec)
153+
buildIntegrationFlow(IntegrationFlow.from(messageSourceSpec, configurer), flow)
154+
}
155+
156+
/**
157+
* Functional {@link IntegrationFlow} definition in Groovy DSL for
158+
* {@link IntegrationFlow#fromSupplier(Supplier, Consumer)} factory method.
159+
*/
160+
static IntegrationFlow integrationFlow(
161+
Closure<Object> source,
162+
@DelegatesTo(value = SourcePollingChannelAdapterSpec, strategy = Closure.DELEGATE_FIRST)
163+
@ClosureParams(value = SimpleType,
164+
options = 'org.springframework.integration.dsl.SourcePollingChannelAdapterSpec')
165+
Closure<?> adapterSpec = null,
166+
@DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST)
167+
@ClosureParams(value = SimpleType,
168+
options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition')
169+
Closure<?> flow) {
170+
171+
Consumer<SourcePollingChannelAdapterSpec> configurer =
172+
GroovyIntegrationFlowDefinition.createConfigurerIfAny(adapterSpec)
173+
buildIntegrationFlow(IntegrationFlow.fromSupplier(source, configurer), flow)
174+
}
175+
176+
/**
177+
* Functional {@link IntegrationFlow} definition in Groovy DSL for
178+
* {@link IntegrationFlow#from(Publisher)} factory method.
179+
*/
180+
static IntegrationFlow integrationFlow(
181+
Publisher<? extends Message<?>> publisher,
182+
@DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST)
183+
@ClosureParams(value = SimpleType,
184+
options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition')
185+
Closure<?> flow) {
186+
187+
buildIntegrationFlow(IntegrationFlow.from(publisher), flow)
188+
}
189+
190+
/**
191+
* Functional {@link IntegrationFlow} definition in Groovy DSL for
192+
* {@link IntegrationFlow#from(MessagingGatewaySupport)} factory method.
193+
*/
194+
static IntegrationFlow integrationFlow(
195+
MessagingGatewaySupport gateway,
196+
@DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST)
197+
@ClosureParams(value = SimpleType,
198+
options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition')
199+
Closure<?> flow) {
200+
201+
buildIntegrationFlow(IntegrationFlow.from(gateway), flow)
202+
}
203+
204+
/**
205+
* Functional {@link IntegrationFlow} definition in Groovy DSL for
206+
* {@link IntegrationFlow#from(org.springframework.integration.dsl.MessagingGatewaySpec)} factory method.
207+
*/
208+
static IntegrationFlow integrationFlow(
209+
MessagingGatewaySpec gatewaySpec,
210+
@DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST)
211+
@ClosureParams(value = SimpleType,
212+
options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition')
213+
Closure<?> flow) {
214+
215+
buildIntegrationFlow(IntegrationFlow.from(gatewaySpec), flow)
216+
}
217+
218+
/**
219+
* Functional {@link IntegrationFlow} definition in Groovy DSL for
220+
* {@link IntegrationFlow#from(MessageProducerSupport)} factory method.
221+
*/
222+
static IntegrationFlow integrationFlow(
223+
MessageProducerSupport producer,
224+
@DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST)
225+
@ClosureParams(value = SimpleType,
226+
options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition')
227+
Closure<?> flow) {
228+
229+
buildIntegrationFlow(IntegrationFlow.from(producer), flow)
230+
}
231+
232+
/**
233+
* Functional {@link IntegrationFlow} definition in Groovy DSL for
234+
* {@link IntegrationFlow#from(org.springframework.integration.dsl.MessageProducerSpec)} factory method.
235+
*/
236+
static IntegrationFlow integrationFlow(
237+
MessageProducerSpec producerSpec,
238+
@DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST)
239+
@ClosureParams(value = SimpleType,
240+
options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition')
241+
Closure<?> flow) {
242+
243+
buildIntegrationFlow(IntegrationFlow.from(producerSpec), flow)
244+
}
245+
246+
/**
247+
* Functional {@link IntegrationFlow} definition in Groovy DSL for
248+
* {@link IntegrationFlow#from(IntegrationFlow)} factory method.
249+
*/
250+
static IntegrationFlow integrationFlow(
251+
IntegrationFlow sourceFlow,
252+
@DelegatesTo(value = GroovyIntegrationFlowDefinition, strategy = Closure.DELEGATE_FIRST)
253+
@ClosureParams(value = SimpleType,
254+
options = 'org.springframework.integration.groovy.dsl.GroovyIntegrationFlowDefinition')
255+
Closure<?> flow) {
256+
257+
buildIntegrationFlow(IntegrationFlow.from(sourceFlow), flow)
258+
}
259+
260+
private static IntegrationFlow buildIntegrationFlow(IntegrationFlowBuilder flowBuilder, Closure<?> flow) {
261+
flow.delegate = new GroovyIntegrationFlowDefinition(flowBuilder)
262+
flow.resolveStrategy = Closure.DELEGATE_FIRST
263+
flow()
264+
flowBuilder.get()
265+
}
266+
267+
private IntegrationGroovyDsl() {
268+
}
269+
270+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/**
2+
* Provides Spring Integration Groovy DSL.
3+
*/
4+
package org.springframework.integration.groovy.dsl

0 commit comments

Comments
 (0)