GH-654 Update routing and RSocket routing documentation with details on 'MessageRoutingCallback'
Resolves #654
This commit is contained in:
@@ -142,7 +142,47 @@ public class RoutingFunction implements Function<Object, Object> {
|
|||||||
. . .
|
. . .
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
The routing instructions could be communicated in several ways;
|
The routing instructions could be communicated in several ways. We support providing instructions via Message headers, System
|
||||||
|
properties as well as pluggable strategy. So let's look at some of the details
|
||||||
|
|
||||||
|
*MessageRoutingCallback*
|
||||||
|
|
||||||
|
The `MessageRoutingCallback` is a strategy to assist with determining the name of the route-to function definition.
|
||||||
|
|
||||||
|
[source, java]
|
||||||
|
----
|
||||||
|
public interface MessageRoutingCallback {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines the name of the function definition to route incoming {@link Message}.
|
||||||
|
*
|
||||||
|
* @param message instance of incoming {@link Message}
|
||||||
|
* @return the name of the route-to function definition
|
||||||
|
*/
|
||||||
|
String functionDefinition(Message<?> message);
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
All you need to do is implement it and and register it as a bean. The framework will automatically
|
||||||
|
pick it up and use it for routing decisions.
|
||||||
|
For example
|
||||||
|
|
||||||
|
[source, java]
|
||||||
|
----
|
||||||
|
@Bean
|
||||||
|
public MessageRoutingCallback customRouter() {
|
||||||
|
return new MessageRoutingCallback() {
|
||||||
|
@Override
|
||||||
|
public String functionDefinition(Message<?> message) {
|
||||||
|
return (String) message.getHeaders().get("func_name");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
----
|
||||||
|
|
||||||
|
In the preceding example you can see a very simple implementation of `MessageRoutingCallback` which determines the function definition from
|
||||||
|
`func_name` header of the incoming Message.
|
||||||
|
|
||||||
|
|
||||||
*Message Headers*
|
*Message Headers*
|
||||||
|
|
||||||
@@ -170,8 +210,26 @@ or `spring.cloud.function.routing-expression` as application properties. The rul
|
|||||||
previous section apply here as well. The only difference is you provide these instructions as
|
previous section apply here as well. The only difference is you provide these instructions as
|
||||||
application properties (e.g., `--spring.cloud.function.definition=foo`).
|
application properties (e.g., `--spring.cloud.function.definition=foo`).
|
||||||
|
|
||||||
|
NOTE: It is important to understand that providing `spring.cloud.function.definition`
|
||||||
|
or `spring.cloud.function.routing-expression` as Message headers will only work for imperative functions (e.g., `Function<Foo, Bar>`).
|
||||||
|
That is to say that we can _only_ route ***per-message*** with imperative functions. With reactive functions we can not route
|
||||||
|
***per-message***. Therefore you can only provide your routing instructions as Application Properties.
|
||||||
|
It's all about unit-of-work. In imperative function unit of work is Message so we can route based on such unit-of-work.
|
||||||
|
With reactive function unit-of-work is the entire stream, so we'll act only on the instruction provided via application
|
||||||
|
properties and route the entire stream.
|
||||||
|
|
||||||
|
*Order of priority for routing instructions*
|
||||||
|
|
||||||
|
Given that we have several mechanisms of providing routing instructions it is important to understand the priorities for
|
||||||
|
conflict resolutions in the event multiple mechanisms are used at the same time, so here is the order:
|
||||||
|
|
||||||
|
1. `MessageRoutingCallback` (If function is imperative will take over regardless if anything else is defined)
|
||||||
|
2. Message Headers (If function is imperative and no `MessageRoutingCallback` provided)
|
||||||
|
3. Application Properties (Any function)
|
||||||
|
|
||||||
|
|
||||||
*Function Filtering*
|
*Function Filtering*
|
||||||
Filtering is the type of routing where there are only tow paths - 'go' or 'discard'. In terms of functions it mean
|
Filtering is the type of routing where there are only two paths - 'go' or 'discard'. In terms of functions it mean
|
||||||
you only want to invoke a certain function if some condition returns 'true', otherwise you want to discard input.
|
you only want to invoke a certain function if some condition returns 'true', otherwise you want to discard input.
|
||||||
However, when it comes to discarding input there are many interpretation of what it could mean in the context of your application.
|
However, when it comes to discarding input there are many interpretation of what it could mean in the context of your application.
|
||||||
For example, you may want to log it, or you may want to maintain the counter of discarded messages. you may also want to do nothing at all.
|
For example, you may want to log it, or you may want to maintain the counter of discarded messages. you may also want to do nothing at all.
|
||||||
|
|||||||
@@ -55,19 +55,22 @@ rsocketRequesterBuilder.tcp("localhost", port)
|
|||||||
.subscribe(System.out::println);
|
.subscribe(System.out::println);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Function Definitions
|
### Order of priority for routing instructions
|
||||||
|
|
||||||
As you can see from the preceding example, we provide function definition as a value to `route(..)` operator of `RSocketRequester.Builder`.
|
As you can see from the preceding example, we provide function definition as a value to `route(..)` operator of `RSocketRequester.Builder`.
|
||||||
However that is not the only way. You can also use standard `spring.cloud.function.definition` property as well as `spring.cloud.function.routing-expression` property.
|
However that is not the only way. You can also use standard `spring.cloud.function.definition` property as well as `spring.cloud.function.routing-expression` or property or `MessageRoutingCallback` on the server side of the RSocket interaction (see "Function Routing and Filtering" section of reference manual).
|
||||||
This raises a question of _order_ and _priorities_ when it comes to reconsiling a conflict in the event several ways of providing definition are used. So it is a mater of clearly stating the rule whcih is:
|
This raises a question of _order_ and _priorities_ when it comes to reconsiling a conflict in the event several ways of providing definition are used. So it is a mater of clearly stating the rule whcih is:
|
||||||
|
|
||||||
***1 - spring.cloud.function.routing-expression***
|
***1 - MessageRoutingCallback***
|
||||||
The `spring.cloud.function.routing-expression` property takes precedence over all other ways of providing definition. So, in the event you may have also use `route(..)` operator or `spring.cloud.function.definition` property, they will be ignored if `spring.cloud.function.routing-expression` property is provided.
|
The `MessageRoutingCallback` takes precedence over all other ways of providing function definition resolution.
|
||||||
|
|
||||||
***2 - route(..)***
|
***2 - spring.cloud.function.routing-expression***
|
||||||
|
The `spring.cloud.function.routing-expression` property takes next precedence. So, in the event you may have also use `route(..)` operator or `spring.cloud.function.definition` property, they will be ignored if `spring.cloud.function.routing-expression` property is provided.
|
||||||
|
|
||||||
|
***3 - route(..)***
|
||||||
The next in line is `route(..)` operator. So in the event there are no `spring.cloud.function.routing-expression` property but you defined `spring.cloud.function.definition` property, it will be ignored in favor of definition provided by the `route(..)` operator.
|
The next in line is `route(..)` operator. So in the event there are no `spring.cloud.function.routing-expression` property but you defined `spring.cloud.function.definition` property, it will be ignored in favor of definition provided by the `route(..)` operator.
|
||||||
|
|
||||||
***3 - spring.cloud.function.definition***
|
***4 - spring.cloud.function.definition***
|
||||||
The `spring.cloud.function.definition` property is the last in the list allowing you to simply `route("")` to empty string.
|
The `spring.cloud.function.definition` property is the last in the list allowing you to simply `route("")` to empty string.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user