GH-944 Remove deprecations and update documentation for MessageRoutingCallback

Resolves #944
This commit is contained in:
Oleg Zhurakousky
2022-10-25 16:01:06 +02:00
parent e5302f255d
commit fd65decdb6
5 changed files with 9 additions and 67 deletions

View File

@@ -193,17 +193,6 @@ public MessageRoutingCallback customRouter() {
In the preceding example you can see a very simple implementation of `MessageRoutingCallback` which determines the function definition from
`func_name` Message header of the incoming Message and returns the instance of `FunctionRoutingResult` containing the definition of function to invoke.
Additionally, the `FunctionRoutingResult` provides another constructor allowing you to provide an instance of `Message` as second argument to be used down stream.
This is primarily for runtime optimizations. To better understand this case let's look at the following scenario.
You need to route based on the payoload type. However, an input Message typically comes in as let's say JSON payload (as `byte[]`) . In order
to determine the route-to function definition you need to first process such JSON and potentially create an instance of the target type.
Once that determination is done you can pass it to `RoutingFunction` which still has a reference to the original Message with un-processed payload
This means that somewhere downstream, type conversion/transformation would need to be repeated.
Allowing you to create a new `Message` with converted payload as part of the `FunctionRoutingResult` will instruct `RoutingFunction` to use such `Message`
downstream. So effectively you letting the framework to benefit from the work you already did.
*Message Headers*
If the input argument is of type `Message<?>`, you can communicate routing instruction by setting one of

View File

@@ -32,17 +32,9 @@ import org.springframework.messaging.Message;
*/
public interface MessageRoutingCallback {
/**
* @deprecated in 3.1 in favor of {@link #routingResult(Message)}
*/
@Deprecated
default String functionDefinition(Message<?> message) {
return null;
}
/**
* Computes and returns the instance of {@link FunctionRoutingResult} which encapsulates,
* at the very minimum, function definition and optionally Message to be used downstream.
* at the very minimum, function definition.
* <br><br>
* Providing such message is primarily an optimization feature. It could be useful for cases
* where routing procedure is complex and results in, let's say, conversion of the payload to
@@ -52,39 +44,7 @@ public interface MessageRoutingCallback {
* @param message input message
* @return instance of {@link FunctionRoutingResult} containing the result of the routing computation
*/
default FunctionRoutingResult routingResult(Message<?> message) {
return new FunctionRoutingResult(functionDefinition(message));
}
/**
* Domain object that represents the result of the {@link MessageRoutingCallback#routingResult(Message)}
* computation. It consists of function definition and optional Message to be used downstream
* (see {@link MessageRoutingCallback#routingResult(Message)} for more details.
*
* @author Oleg Zhurakousky
*
*/
final class FunctionRoutingResult {
private final String functionDefinition;
private final Message<?> message;
FunctionRoutingResult(String functionDefinition, Message<?> message) {
this.functionDefinition = functionDefinition;
this.message = message;
}
public FunctionRoutingResult(String functionDefinition) {
this(functionDefinition, null);
}
public String getFunctionDefinition() {
return functionDefinition;
}
public Message<?> getMessage() {
return message;
}
default String routingResult(Message<?> message) {
return (String) message.getHeaders().get(FunctionProperties.FUNCTION_DEFINITION);
}
}

View File

@@ -28,7 +28,6 @@ import reactor.core.publisher.Mono;
import org.springframework.cloud.function.context.FunctionCatalog;
import org.springframework.cloud.function.context.FunctionProperties;
import org.springframework.cloud.function.context.MessageRoutingCallback;
import org.springframework.cloud.function.context.MessageRoutingCallback.FunctionRoutingResult;
import org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry.FunctionInvocationWrapper;
import org.springframework.cloud.function.context.message.MessageUtils;
import org.springframework.context.expression.MapAccessor;
@@ -123,14 +122,9 @@ public class RoutingFunction implements Function<Object, Object> {
if (input instanceof Message) {
Message<?> message = (Message<?>) input;
if (this.routingCallback != null) {
FunctionRoutingResult routingResult = this.routingCallback.routingResult(message);
if (routingResult != null) {
if (StringUtils.hasText(routingResult.getFunctionDefinition())) {
function = this.functionFromDefinition(routingResult.getFunctionDefinition());
}
if (routingResult.getMessage() != null) {
message = routingResult.getMessage();
}
String functionDefinition = this.routingCallback.routingResult(message);
if (StringUtils.hasText(functionDefinition)) {
function = this.functionFromDefinition(functionDefinition);
}
}
if (function == null) {

View File

@@ -80,7 +80,7 @@ public class MessageRoutingCallbackTests {
return new MessageRoutingCallback() {
@Override
public FunctionRoutingResult routingResult(Message<?> message) {
public String routingResult(Message<?> message) {
String payload = new String((byte[]) message.getPayload());
MessageBuilder<?> builder;
@@ -95,8 +95,7 @@ public class MessageRoutingCallbackTests {
}
Message<?> m = builder.copyHeaders(message.getHeaders()).build();
createdMessageIds.put(functionDefinition, m.getHeaders().getId());
FunctionRoutingResult functionRoutingResult = new FunctionRoutingResult(functionDefinition, m);
return functionRoutingResult;
return functionDefinition;
}
};
}

View File

@@ -109,7 +109,7 @@ public class MessageRoutingCallbackRSocketTests {
public MessageRoutingCallback customRouter() {
return new MessageRoutingCallback() {
@Override
public String functionDefinition(Message<?> message) {
public String routingResult(Message<?> message) {
return (String) message.getHeaders().get("func_name");
}
};