Skip to content

Commit 33d13a4

Browse files
GH-8583: Add Java & DSL samples into docs (#8608)
* GH-8583: Add Java & DSL samples into docs Fixes #8583 When users jump into docs first thing these days they expect to see a Java DSL sample. * Fix language in Docs Co-authored-by: Gary Russell <[email protected]> * * Improve `router.adoc` for DSL samples * Add links to DSL chapters --------- Co-authored-by: Gary Russell <[email protected]>
1 parent 212bd46 commit 33d13a4

File tree

5 files changed

+423
-27
lines changed

5 files changed

+423
-27
lines changed

src/reference/asciidoc/filter.adoc

+44-1
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,54 @@ MessageFilter filter = new MessageFilter(someSelector);
3131
----
3232
====
3333

34-
In combination with the namespace and SpEL, you can configure powerful filters with very little Java code.
34+
[[filter-dsl]]
35+
==== Configuring a Filter with Java, Groovy and Kotlin DSLs
36+
37+
The `IntegrationFlowBuilder` provided by the Java DSL (which is also used as a base for the Groovy and Kotlin DSLs) provides a number of overloaded methods for the `filter()` operator.
38+
The `MessageSelector` abstraction mentioned above can be used as a Lambda in a `filter()` definition:
39+
40+
====
41+
[source, java, role="primary"]
42+
.Java DSL
43+
----
44+
@Bean
45+
public IntegrationFlow someFlow() {
46+
return f -> f
47+
.<String>filter((payload) -> !"junk".equals(payload));
48+
}
49+
----
50+
[source, kotlin, role="secondary"]
51+
.Kotlin DSL
52+
----
53+
@Bean
54+
fun someFlow() =
55+
integrationFlow {
56+
filter<String> { it != "junk" }
57+
}
58+
----
59+
[source, groovy, role="secondary"]
60+
.Groovy DSL
61+
----
62+
@Bean
63+
someFlow() {
64+
integrationFlow {
65+
filter String, { it != 'junk' }
66+
}
67+
}
68+
----
69+
====
70+
71+
See more information about DSLs in the respective chapters:
72+
73+
* <<./dsl.adoc#java-dsl,Java DSL>>
74+
* <<./kotlin-dsl.adoc#kotlin-dsl,Kotlin DSL>>
75+
* <<./groovy-dsl.adoc#groovy-dsl,Groovy DSL>>
3576

3677
[[filter-xml]]
3778
==== Configuring a Filter with XML
3879

80+
In combination with the namespace and SpEL, you can configure powerful filters with very little Java code.
81+
3982
You can use the `<filter>` element is used to create a message-selecting endpoint.
4083
In addition to `input-channel` and `output-channel` attributes, it requires a `ref` attribute.
4184
The `ref` can point to a `MessageSelector` implementation, as the following example shows:

src/reference/asciidoc/router.adoc

+44-3
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,7 @@ It is a "`registering an interest in something that is part of the message`" use
739739
Because of the runtime management operation for the `<recipient-list-router>`, it can be configured without any `<recipient>` from the start.
740740
In this case, the behavior of `RecipientListRouter` is the same when there is no one matching recipient for the message.
741741
If `defaultOutputChannel` is configured, the message is sent there.
742-
Otherwise the `MessageDeliveryException` is thrown.
742+
Otherwise, the `MessageDeliveryException` is thrown.
743743

744744
[[router-implementations-xpath-router]]
745745
===== XPath Router
@@ -762,7 +762,47 @@ NOTE: Since version 4.3 the `ErrorMessageExceptionTypeRouter` loads all mapping
762762

763763
The following example shows a sample configuration for `ErrorMessageExceptionTypeRouter`:
764764

765-
[source,xml]
765+
====
766+
[source, java, role="primary"]
767+
.Java DSL
768+
----
769+
@Bean
770+
public IntegrationFlow someFlow() {
771+
return f -> f
772+
.routeByException(r -> r
773+
.channelMapping(IllegalArgumentException.class, "illegalChannel")
774+
.channelMapping(NullPointerException.class, "npeChannel")
775+
.defaultOutputChannel("defaultChannel"));
776+
}
777+
----
778+
[source, kotlin, role="secondary"]
779+
.Kotlin DSL
780+
----
781+
@Bean
782+
fun someFlow() =
783+
integrationFlow {
784+
routeByException {
785+
channelMapping(IllegalArgumentException::class.java, "illegalChannel")
786+
channelMapping(NullPointerException::class.java, "npeChannel")
787+
defaultOutputChannel("defaultChannel")
788+
}
789+
}
790+
----
791+
[source, groovy, role="secondary"]
792+
.Groovy DSL
793+
----
794+
@Bean
795+
someFlow() {
796+
integrationFlow {
797+
routeByException {
798+
channelMapping IllegalArgumentException, 'illegalChannel'
799+
channelMapping NullPointerException, 'npeChannel'
800+
defaultOutputChannel 'defaultChannel'
801+
}
802+
}
803+
}
804+
----
805+
[source, xml, role="secondary"]
766806
----
767807
<int:exception-type-router input-channel="inputChannel"
768808
default-output-channel="defaultChannel">
@@ -775,6 +815,7 @@ The following example shows a sample configuration for `ErrorMessageExceptionTyp
775815
<int:channel id="illegalChannel" />
776816
<int:channel id="npeChannel" />
777817
----
818+
====
778819

779820
[[router-namespace]]
780821
==== Configuring a Generic Router
@@ -1115,7 +1156,7 @@ That basically involves a bean lookup for the provided name.
11151156
Now all messages that contain the header-value pair as `testHeader=kermit` are going to be routed to a `MessageChannel` whose bean name (its `id`) is 'kermit'.
11161157

11171158
But what if you want to route these messages to the 'simpson' channel? Obviously changing a static configuration works, but doing so also requires bringing your system down.
1118-
However, if you have had an access to the channel identifier map, you could introduce a new mapping where the header-value pair is now `kermit=simpson`, thus letting the second step treat 'kermit' as a channel identifier while resolving it to 'simpson' as the channel name.
1159+
However, if you have had access to the channel identifier map, you could introduce a new mapping where the header-value pair is now `kermit=simpson`, thus letting the second step treat 'kermit' as a channel identifier while resolving it to 'simpson' as the channel name.
11191160

11201161
The same obviously applies for `PayloadTypeRouter`, where you can now remap or remove a particular payload type mapping.
11211162
In fact, it applies to every other router, including expression-based routers, since their computed values now have a chance to go through the second step to be resolved to the actual `channel name`.

src/reference/asciidoc/service-activator.adoc

+62-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,67 @@ As with most of the configuration options described here, the same behavior actu
1010
[[service-activator-namespace]]
1111
==== Configuring Service Activator
1212

13-
To create a service activator, use the 'service-activator' element with the 'input-channel' and 'ref' attributes, as the following example shows:
13+
With Java & Annotation configuration, it is sufficient to mark the respective service method with the `@ServiceActivator` annotation - and the framework calls it when messages are consumed from an input channel:
14+
15+
====
16+
[source,java]
17+
----
18+
public class SomeService {
19+
20+
@ServiceActivator(inputChannel = "exampleChannel")
21+
public void exampleHandler(SomeData payload) {
22+
...
23+
}
24+
25+
}
26+
----
27+
====
28+
29+
See more information in the <<./configuration.adoc#annotations, Annotation Support>>.
30+
31+
For Java, Groovy or Kotlin DSLs, the `.handle()` operator of an `IntegrationFlow` represents a service activator:
32+
33+
====
34+
[source, java, role="primary"]
35+
.Java DSL
36+
----
37+
@Bean
38+
public IntegrationFlow someFlow() {
39+
return IntegrationFlow
40+
.from("exampleChannel")
41+
.handle(someService, "exampleHandler")
42+
.get();
43+
}
44+
----
45+
[source, kotlin, role="secondary"]
46+
.Kotlin DSL
47+
----
48+
@Bean
49+
fun someFlow() =
50+
integrationFlow("exampleChannel") {
51+
handle(someService, "exampleHandler")
52+
}
53+
----
54+
[source, groovy, role="secondary"]
55+
.Groovy DSL
56+
----
57+
@Bean
58+
someFlow() {
59+
integrationFlow 'exampleChannel',
60+
{
61+
handle someService, 'exampleHandler'
62+
}
63+
}
64+
----
65+
====
66+
67+
See more information about the DSLs in the respective chapters:
68+
69+
* <<./dsl.adoc#java-dsl,Java DSL>>
70+
* <<./kotlin-dsl.adoc#kotlin-dsl,Kotlin DSL>>
71+
* <<./groovy-dsl.adoc#groovy-dsl,Groovy DSL>>
72+
73+
To create a service activator when using XML configuration, use the 'service-activator' element with the 'input-channel' and 'ref' attributes, as the following example shows:
1474

1575
====
1676
[source,xml]
@@ -59,7 +119,7 @@ If it can be resolved, the message is sent there.
59119
If the request message does not have a `replyChannel` header and the `reply` object is a `Message`, its `replyChannel` header is consulted for a target destination.
60120
This is the technique used for request-reply messaging in Spring Integration, and it is also an example of the return address pattern.
61121

62-
If your method returns a result and you want to discard it and end the flow, you should configure the `output-channel` to send to a `NullChannel`.
122+
If your method returns a result, and you want to discard it and end the flow, you should configure the `output-channel` to send to a `NullChannel`.
63123
For convenience, the framework registers one with the name, `nullChannel`.
64124
See <<./channel.adoc#channel-special-channels,Special Channels>> for more information.
65125

src/reference/asciidoc/splitter.adoc

+41-1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,46 @@ Starting with version 5.2, the splitter supports a `discardChannel` option for s
6969
In this case there is just no item to iterate for sending to the `outputChannel`.
7070
The `null` splitting result remains as an end of flow indicator.
7171

72+
==== Configuring a Splitter with Java, Groovy and Kotlin DSLs
73+
74+
An example of simple splitter based on a `Message` and its iterable payload with DSL configuration:
75+
76+
====
77+
[source, java, role="primary"]
78+
.Java DSL
79+
----
80+
@Bean
81+
public IntegrationFlow someFlow() {
82+
return f -> f.split(Message.class, Message::getPayload);
83+
}
84+
----
85+
[source, kotlin, role="secondary"]
86+
.Kotlin DSL
87+
----
88+
@Bean
89+
fun someFlow() =
90+
integrationFlow {
91+
split<Message<*>> { it.payload }
92+
}
93+
----
94+
[source, groovy, role="secondary"]
95+
.Groovy DSL
96+
----
97+
@Bean
98+
someFlow() {
99+
integrationFlow {
100+
split Message<?>, { it.payload }
101+
}
102+
}
103+
----
104+
====
105+
106+
See more information about the DSLs in the respective chapters:
107+
108+
* <<./dsl.adoc#java-dsl,Java DSL>>
109+
* <<./kotlin-dsl.adoc#kotlin-dsl,Kotlin DSL>>
110+
* <<./groovy-dsl.adoc#groovy-dsl,Groovy DSL>>
111+
72112
==== Configuring a Splitter with XML
73113

74114
A splitter can be configured through XML as follows:
@@ -142,4 +182,4 @@ List<LineItem> extractItems(Order order) {
142182
----
143183
====
144184

145-
See also <<./handler-advice.adoc#advising-with-annotations,Advising Endpoints Using Annotations>>, <<./dsl.adoc#java-dsl-splitters,Splitters>> and <<./file.adoc#file-splitter, File Splitter>>.
185+
See also <<./handler-advice.adoc#advising-with-annotations,Advising Endpoints Using Annotations>> and <<./file.adoc#file-splitter, File Splitter>>.

0 commit comments

Comments
 (0)