Skip to content

GH-8583: Add Java & DSL samples into docs #8608

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 44 additions & 1 deletion src/reference/asciidoc/filter.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,54 @@ MessageFilter filter = new MessageFilter(someSelector);
----
====

In combination with the namespace and SpEL, you can configure powerful filters with very little Java code.
[[filter-dsl]]
==== Configuring a Filter with Java, Groovy and Kotlin DSLs

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.
The `MessageSelector` abstraction mentioned above can be used as a Lambda in a `filter()` definition:

====
[source, java, role="primary"]
.Java DSL
----
@Bean
public IntegrationFlow someFlow() {
return f -> f
.<String>filter((payload) -> !"junk".equals(payload));
}
----
[source, kotlin, role="secondary"]
.Kotlin DSL
----
@Bean
fun someFlow() =
integrationFlow {
filter<String> { it != "junk" }
}
----
[source, groovy, role="secondary"]
.Groovy DSL
----
@Bean
someFlow() {
integrationFlow {
filter String, { it != 'junk' }
}
}
----
====

See more information about DSLs in the respective chapters:

* <<./dsl.adoc#java-dsl,Java DSL>>
* <<./kotlin-dsl.adoc#kotlin-dsl,Kotlin DSL>>
* <<./groovy-dsl.adoc#groovy-dsl,Groovy DSL>>

[[filter-xml]]
==== Configuring a Filter with XML

In combination with the namespace and SpEL, you can configure powerful filters with very little Java code.

You can use the `<filter>` element is used to create a message-selecting endpoint.
In addition to `input-channel` and `output-channel` attributes, it requires a `ref` attribute.
The `ref` can point to a `MessageSelector` implementation, as the following example shows:
Expand Down
47 changes: 44 additions & 3 deletions src/reference/asciidoc/router.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,7 @@ It is a "`registering an interest in something that is part of the message`" use
Because of the runtime management operation for the `<recipient-list-router>`, it can be configured without any `<recipient>` from the start.
In this case, the behavior of `RecipientListRouter` is the same when there is no one matching recipient for the message.
If `defaultOutputChannel` is configured, the message is sent there.
Otherwise the `MessageDeliveryException` is thrown.
Otherwise, the `MessageDeliveryException` is thrown.

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

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

[source,xml]
====
[source, java, role="primary"]
.Java DSL
----
@Bean
public IntegrationFlow someFlow() {
return f -> f
.routeByException(r -> r
.channelMapping(IllegalArgumentException.class, "illegalChannel")
.channelMapping(NullPointerException.class, "npeChannel")
.defaultOutputChannel("defaultChannel"));
}
----
[source, kotlin, role="secondary"]
.Kotlin DSL
----
@Bean
fun someFlow() =
integrationFlow {
routeByException {
channelMapping(IllegalArgumentException::class.java, "illegalChannel")
channelMapping(NullPointerException::class.java, "npeChannel")
defaultOutputChannel("defaultChannel")
}
}
----
[source, groovy, role="secondary"]
.Groovy DSL
----
@Bean
someFlow() {
integrationFlow {
routeByException {
channelMapping IllegalArgumentException, 'illegalChannel'
channelMapping NullPointerException, 'npeChannel'
defaultOutputChannel 'defaultChannel'
}
}
}
----
[source, xml, role="secondary"]
----
<int:exception-type-router input-channel="inputChannel"
default-output-channel="defaultChannel">
Expand All @@ -775,6 +815,7 @@ The following example shows a sample configuration for `ErrorMessageExceptionTyp
<int:channel id="illegalChannel" />
<int:channel id="npeChannel" />
----
====

[[router-namespace]]
==== Configuring a Generic Router
Expand Down Expand Up @@ -1115,7 +1156,7 @@ That basically involves a bean lookup for the provided name.
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'.

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.
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.
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.

The same obviously applies for `PayloadTypeRouter`, where you can now remap or remove a particular payload type mapping.
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`.
Expand Down
64 changes: 62 additions & 2 deletions src/reference/asciidoc/service-activator.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,67 @@ As with most of the configuration options described here, the same behavior actu
[[service-activator-namespace]]
==== Configuring Service Activator

To create a service activator, use the 'service-activator' element with the 'input-channel' and 'ref' attributes, as the following example shows:
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:

====
[source,java]
----
public class SomeService {

@ServiceActivator(inputChannel = "exampleChannel")
public void exampleHandler(SomeData payload) {
...
}

}
----
====

See more information in the <<./configuration.adoc#annotations, Annotation Support>>.

For Java, Groovy or Kotlin DSLs, the `.handle()` operator of an `IntegrationFlow` represents a service activator:

====
[source, java, role="primary"]
.Java DSL
----
@Bean
public IntegrationFlow someFlow() {
return IntegrationFlow
.from("exampleChannel")
.handle(someService, "exampleHandler")
.get();
}
----
[source, kotlin, role="secondary"]
.Kotlin DSL
----
@Bean
fun someFlow() =
integrationFlow("exampleChannel") {
handle(someService, "exampleHandler")
}
----
[source, groovy, role="secondary"]
.Groovy DSL
----
@Bean
someFlow() {
integrationFlow 'exampleChannel',
{
handle someService, 'exampleHandler'
}
}
----
====

See more information about the DSLs in the respective chapters:

* <<./dsl.adoc#java-dsl,Java DSL>>
* <<./kotlin-dsl.adoc#kotlin-dsl,Kotlin DSL>>
* <<./groovy-dsl.adoc#groovy-dsl,Groovy DSL>>

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:

====
[source,xml]
Expand Down Expand Up @@ -59,7 +119,7 @@ If it can be resolved, the message is sent there.
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.
This is the technique used for request-reply messaging in Spring Integration, and it is also an example of the return address pattern.

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`.
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`.
For convenience, the framework registers one with the name, `nullChannel`.
See <<./channel.adoc#channel-special-channels,Special Channels>> for more information.

Expand Down
42 changes: 41 additions & 1 deletion src/reference/asciidoc/splitter.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,46 @@ Starting with version 5.2, the splitter supports a `discardChannel` option for s
In this case there is just no item to iterate for sending to the `outputChannel`.
The `null` splitting result remains as an end of flow indicator.

==== Configuring a Splitter with Java, Groovy and Kotlin DSLs

An example of simple splitter based on a `Message` and its iterable payload with DSL configuration:

====
[source, java, role="primary"]
.Java DSL
----
@Bean
public IntegrationFlow someFlow() {
return f -> f.split(Message.class, Message::getPayload);
}
----
[source, kotlin, role="secondary"]
.Kotlin DSL
----
@Bean
fun someFlow() =
integrationFlow {
split<Message<*>> { it.payload }
}
----
[source, groovy, role="secondary"]
.Groovy DSL
----
@Bean
someFlow() {
integrationFlow {
split Message<?>, { it.payload }
}
}
----
====

See more information about the DSLs in the respective chapters:

* <<./dsl.adoc#java-dsl,Java DSL>>
* <<./kotlin-dsl.adoc#kotlin-dsl,Kotlin DSL>>
* <<./groovy-dsl.adoc#groovy-dsl,Groovy DSL>>

==== Configuring a Splitter with XML

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

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>>.
See also <<./handler-advice.adoc#advising-with-annotations,Advising Endpoints Using Annotations>> and <<./file.adoc#file-splitter, File Splitter>>.
Loading