From d00a3b9a2e05958a584a02bf096544ba4aa49eee Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Mon, 10 May 2021 16:51:18 -0400 Subject: [PATCH] Code switcher in the channel-adapter.adoc --- src/reference/asciidoc/channel-adapter.adoc | 115 ++++++++++++++++++-- 1 file changed, 106 insertions(+), 9 deletions(-) diff --git a/src/reference/asciidoc/channel-adapter.adoc b/src/reference/asciidoc/channel-adapter.adoc index 2f7bee13c1..47ae4c150a 100644 --- a/src/reference/asciidoc/channel-adapter.adoc +++ b/src/reference/asciidoc/channel-adapter.adoc @@ -11,14 +11,63 @@ These provide an easy way to extend Spring Integration, as long as you have a me [[channel-adapter-namespace-inbound]] ==== Configuring An Inbound Channel Adapter -An `inbound-channel-adapter` element can invoke any method on a Spring-managed object and send a non-null return value to a `MessageChannel` after converting the method's output to a `Message`. +An `inbound-channel-adapter` element (a `SourcePollingChannelAdapter` in Java configuration) can invoke any method on a Spring-managed object and send a non-null return value to a `MessageChannel` after converting the method's output to a `Message`. When the adapter's subscription is activated, a poller tries to receive messages from the source. The poller is scheduled with the `TaskScheduler` according to the provided configuration. To configure the polling interval or cron expression for an individual channel adapter, you can provide a 'poller' element with one of the scheduling attributes, such as 'fixed-rate' or 'cron'. The following example defines two `inbound-channel-adapter` instances: ==== -[source,xml] +[source, java, role="primary"] +.Java DSL +---- +@Bean +public IntegrationFlow source1() { + return IntegrationFlows.from(() -> new GenericMessage<>(...), + e -> e.poller(p -> p.fixedRate(5000))) + ... + .get(); +} + +@Bean +public IntegrationFlow source2() { + return IntegrationFlows.from(() -> new GenericMessage<>(...), + e -> e.poller(p -> p.cron("30 * 9-17 * * MON-FRI"))) + ... + .get(); +} +---- +[source, java, role="secondary"] +.Java +---- +public class SourceService { + + @InboundChannelAdapter(channel = "channel1", poller = @Poller(fixedRate = "5000")) + Object method1() { + ... + } + + @InboundChannelAdapter(channel = "channel2", poller = @Poller(cron = "30 * 9-17 * * MON-FRI")) + Object method2() { + ... + } +} +---- +==== +[source, kotlin, role="secondary"] +.Kotlin DSL +---- +@Bean +fun messageSourceFlow() = + integrationFlow( { GenericMessage<>(...) }, + { poller { it.fixedRate(5000) } }) { + ... + } +---- +==== +---- +[source, xml, role="secondary"] +.XML ---- @@ -38,7 +87,7 @@ See <<./endpoint.adoc#endpoint-namespace,Endpoint Namespace Support>> for more d [IMPORTANT] .Important: Poller Configuration ===== -Some `inbound-channel-adapter` types are backed by a `SourcePollingChannelAdapter`, which means they contain a poller configuration that polls the `MessageSource` (to invoke a custom method that produces the value that becomes a `Message` payload) based on the configuration specified in the Poller. +All the `inbound-channel-adapter` types are backed by a `SourcePollingChannelAdapter`, which means they contain a poller configuration that polls the `MessageSource` (to invoke a custom method that produces the value that becomes a `Message` payload) based on the configuration specified in the Poller. The following example shows the configuration of two pollers: ==== @@ -83,11 +132,45 @@ Starting with version 5.5, a `0` value for `max-messages-per-poll` has a special [[channel-adapter-namespace-outbound]] ==== Configuring An Outbound Channel Adapter -An `outbound-channel-adapter` element can also connect a `MessageChannel` to any POJO consumer method that should be invoked with the payload of messages sent to that channel. +An `outbound-channel-adapter` element (a `@ServiceActivator` for Java configuration) can also connect a `MessageChannel` to any POJO consumer method that should be invoked with the payload of messages sent to that channel. The following example shows how to define an outbound channel adapter: ==== -[source,xml] +[source, java, role="primary"] +.Java DSL +---- +@Bean +public IntegrationFlow outboundChannelAdapterFlow(MyPojo myPojo) { + return f -> f + .handle(myPojo, "handle"); +} +---- +[source, java, role="secondary"] +.Java +---- +public class MyPojo { + + @ServiceActivator(channel = "channel1") + void handle(Object payload) { + ... + } + +} +---- +==== +[source, kotlin, role="secondary"] +.Kotlin DSL +---- +@Bean +fun outboundChannelAdapterFlow(myPojo: MyPojo) = + integrationFlow { + handle(myPojo, "handle") + } +---- +==== +---- +[source, xml, role="secondary"] +.XML ---- @@ -95,10 +178,24 @@ The following example shows how to define an outbound channel adapter: ---- ==== -If the channel being adapted is a `PollableChannel`, you must provide a poller sub-element, as the following example shows: +If the channel being adapted is a `PollableChannel`, you must provide a poller sub-element (the `@Poller` sub-annotation on the `@ServiceActivator`), as the following example shows: ==== -[source,xml] +---- +[source, java, role="primary"] +.Java +---- +public class MyPojo { + + @ServiceActivator(channel = "channel1", poller = @Poller(fixedRate = "3000")) + void handle(Object payload) { + ... + } + +} +---- +[source, xml, role="secondary"] +.XML ---- @@ -152,6 +249,6 @@ See also the `cacheSeconds` property on the `ReloadableResourceBundleExpressionS For more information regarding expressions, see <<./spel.adoc#spel,Spring Expression Language (SpEL)>>. For scripts, see <<./groovy.adoc#groovy,Groovy support>> and <<./scripting.adoc#scripting,Scripting Support>>. -IMPORTANT: The `` is endpoint starts a message flow by periodically triggering to poll some underlying `MessageSource`. +IMPORTANT: The `` (`SourcePollingChannelAdapter`) is an endpoint which starts a message flow by periodically triggering to poll some underlying `MessageSource`. Since, at the time of polling, there is no message object, expressions and scripts do not have access to a root `Message`, so there are no payload or headers properties that are available in most other messaging SpEL expressions. -The script can generate and return a complete `Message` object with headers and payload or only a payload, which is added to a message with basic headers. +The script can generate and return a complete `Message` object with headers and payload or only a payload, which is added to a message with basic headers by the framework.