From b8de26b4f70cb30aa695c3706530d747feb2c0ea Mon Sep 17 00:00:00 2001 From: Oleg Zhurakousky Date: Thu, 31 Oct 2019 14:55:51 +0100 Subject: [PATCH] Polishing routing documentation --- .../main/asciidoc/spring-cloud-stream.adoc | 41 +++++++++++++++---- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/docs/src/main/asciidoc/spring-cloud-stream.adoc b/docs/src/main/asciidoc/spring-cloud-stream.adoc index 3e6f22d0f..209381818 100644 --- a/docs/src/main/asciidoc/spring-cloud-stream.adoc +++ b/docs/src/main/asciidoc/spring-cloud-stream.adoc @@ -1161,11 +1161,14 @@ Routing can be achieved by relying on `RoutingFunction` available in Spring Clou Once enabled `RoutingFunction` will be bound to input destination receiving all the messages and route them to other functions based on the provided instruction. +IMPORTANT: For the purposes of binding the name of the routing destination is `functionRouter-in-0` +(see RoutingFunction.FUNCTION_NAME and binding naming convention <>). + Instruction could be provided with individual messages as well as application properties. Here are couple of samples: -***Using message headers*** +===== Using message headers [source,java] ---- @SpringBootApplication @@ -1191,20 +1194,42 @@ public class SampleApplication { } } ---- -By default `RoutingFunction` will look for `spring.cloud.function.definition` header and if it is found its value will be treated as routing instruction. -So in the above case the value of such header should be either `odd` or `even` (the name of the function beans) to route request to available functions. +By sending message to the `functionRouter-in-0` destination exposed by the binder (i.e., rabbit, kafka), +such message will be routed to the appropriate (‘even’ or ‘odd’) Consumer. + +By default `RoutingFunction` will look for `spring.cloud.function.definition` or `spring.cloud.function.routing-expression` (for more dynamic scenarios with SpEL) +header and if it is found its value will be treated as routing instruction. -You can also use SpEL for more dynamic scenarios via `spring.cloud.function.routing-expression` header. For example, setting `spring.cloud.function.routing-expression` header to value `T(java.lang.System).currentTimeMillis() % 2 == 0 ? 'even' : 'odd'` will end up semi-randomly routing request to either `odd` or `even` functions. Also, for SpEL, the _root object_ of the evaluation context is `Message` so you can do evaluation on individual headers (or message) as well `....routing-expression=headers['type']` -***Using application properties*** +===== Using application properties The `spring.cloud.function.routing-expression` and/or `spring.cloud.function.definition` can be passed as application properties (e.g., `spring.cloud.function.routing-expression=headers['type']`. +[source,java] +---- +@SpringBootApplication +public class RoutingStreamApplication { -Passing instructions via application properties is especially important for reactive functions since given that fact that reactive + public static void main(String[] args) { + SpringApplication.run(RoutingStreamApplication.class, + "--spring.cloud.function.routing-expression=" + + "T(java.lang.System).nanoTime() % 2 == 0 ? 'even' : 'odd'"); + } + @Bean + public Consumer even() { + return value -> System.out.println("EVEN: " + value); + } + + @Bean + public Consumer odd() { + return value -> System.out.println("ODD: " + value); + } +} +---- +IMPORTANT: Passing instructions via application properties is especially important for reactive functions since given that reactive function is only invoked once to pass the Publisher, so access to the individual items is limited. ==== Routing FROM Consumer @@ -1213,7 +1238,7 @@ Aside from static destinations, Spring Cloud Stream lets applications send messa This is useful, for example, when the target destination needs to be determined at runtime. Applications can do so in one of two ways -***BinderAwareChannelResolver*** +===== BinderAwareChannelResolver The `BinderAwareChannelResolver` is a special bean registered automatically by the framework. You can autowire this bean into your application and use it to resolve output destination at runtime @@ -1251,7 +1276,7 @@ curl -H "Content-Type: application/json" -X POST -d "order-1" http://localhost:8 The destinations, 'customers' and 'orders', are created in the broker (in the exchange for Rabbit or in the topic for Kafka) with names of 'customers' and 'orders', and the data is published to the appropriate destinations. -***spring.cloud.stream.sendto.destination*** +===== spring.cloud.stream.sendto.destination You can also delegate to the framework to dynamically resolve the output destination by specifying `spring.cloud.stream.sendto.destination` header set to the name of the destination to be resolved.