GH-317: Add Static Routing Key

Resolves https://github.com/spring-cloud/spring-cloud-stream-binder-rabbit/issues/317

GH-317 Adding static routing key field to producer properties

GH-317 Updating based on PR comments

GH-317 Updating import order based on checkstyle

GH-317 Updating import order based on checkstyle
This commit is contained in:
Adam Benjamin
2021-09-06 13:31:13 -05:00
committed by Gary Russell
parent eee7e63876
commit 1e4f5829fe
4 changed files with 65 additions and 3 deletions

View File

@@ -889,9 +889,13 @@ Applies only when `requiredGroups` are provided and then only to those groups.
Default: none - broker default will apply.
routingKeyExpression::
A SpEL expression to determine the routing key to use when publishing messages.
For a fixed routing key, use a literal expression, such as `routingKeyExpression='my.routingKey'` in a properties file or `routingKeyExpression: '''my.routingKey'''` in a YAML file.
For a fixed routing key, use `routingKey`.
+
Default: `destination` or `destination-<partition>` for partitioned destinations.
routingKey::
A string defining a fixed routing key to use when publishing messages.
+
Default: see `routingKeyExpression`
singleActiveConsumer::
Set to true to set the `x-single-active-consumer` queue property to true.
Applies only when `requiredGroups` are provided and then only to those groups.

View File

@@ -928,9 +928,13 @@ Applies only when `requiredGroups` are provided and then only to those groups.
Default: none - broker default will apply.
routingKeyExpression::
A SpEL expression to determine the routing key to use when publishing messages.
For a fixed routing key, use a literal expression, such as `routingKeyExpression='my.routingKey'` in a properties file or `routingKeyExpression: '''my.routingKey'''` in a YAML file.
For a fixed routing key, use `routingKey`.
+
Default: `destination` or `destination-<partition>` for partitioned destinations.
routingKey::
A string defining a fixed routing key to use when publishing messages.
+
Default: see `routingKeyExpression`
singleActiveConsumer::
Set to true to set the `x-single-active-consumer` queue property to true.
Applies only when `requiredGroups` are provided and then only to those groups.

View File

@@ -16,12 +16,17 @@
package org.springframework.cloud.stream.binder.rabbit.properties;
import java.util.Optional;
import jakarta.validation.constraints.Min;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.expression.Expression;
import org.springframework.expression.common.LiteralExpression;
import org.springframework.util.Assert;
/**
* @author Marius Bogoevici
* @author Gary Russell
@@ -102,6 +107,12 @@ public class RabbitProducerProperties extends RabbitCommonProperties {
*/
private Expression delayExpression;
/**
* a static routing key when publishing messages; default is the destination name;
* suffixed by "-partition" when partitioned. This is only used if `routingKeyExpression` is null
*/
private String routingKey;
/**
* a custom routing key when publishing messages; default is the destination name;
* suffixed by "-partition" when partitioned.
@@ -232,13 +243,24 @@ public class RabbitProducerProperties extends RabbitCommonProperties {
}
public Expression getRoutingKeyExpression() {
return this.routingKeyExpression;
return Optional.ofNullable(this.routingKeyExpression)
.orElseGet(() -> Optional.ofNullable(this.routingKey)
.map(LiteralExpression::new)
.orElse(null));
}
public void setRoutingKeyExpression(Expression routingKeyExpression) {
this.routingKeyExpression = routingKeyExpression;
}
public String getRoutingKey() {
return this.routingKey;
}
public void setRoutingKey(String routingKey) {
this.routingKey = routingKey;
}
public String getConfirmAckChannel() {
return this.confirmAckChannel;
}

View File

@@ -2064,6 +2064,38 @@ public class RabbitBinderTests extends
producerBinding.unbind();
}
@Test
public void testRoutingKey(TestInfo testInfo) throws Exception {
String routingKey = "static.key";
RabbitTestBinder binder = getBinder();
ExtendedProducerProperties<RabbitProducerProperties> producerProperties = createProducerProperties(testInfo);
producerProperties.getExtension().setRoutingKey(routingKey);
DirectChannel output = createBindableChannel("output",
createProducerBindingProperties(producerProperties));
output.setBeanName("rkeProducer");
Binding<MessageChannel> producerBinding = binder.bindProducer("rke", output,
producerProperties);
RabbitAdmin admin = new RabbitAdmin(this.rabbitAvailableRule.getResource());
Queue queue = new AnonymousQueue();
DirectExchange exchange = new DirectExchange("rke");
org.springframework.amqp.core.Binding binding = BindingBuilder.bind(queue)
.to(exchange).with(routingKey);
admin.declareQueue(queue);
admin.declareBinding(binding);
output.send(new GenericMessage<>(new Pojo("rkeTest")));
Object out = spyOn(queue.getName()).receive(false);
assertThat(out).isInstanceOf(byte[].class);
assertThat(new String((byte[]) out, StandardCharsets.UTF_8))
.isEqualTo("{\"field\":\"rkeTest\"}");
producerBinding.unbind();
}
@Test
public void testRoutingKeyExpressionPartitionedAndDelay(TestInfo testInfo) throws Exception {
RabbitTestBinder binder = getBinder();