3
votes

I'm having following testing scenario for Spring Cloud Stream based application. I'm having one topic for my application with two queues. BindingKey for first queue is named "cities", for the second queue is the binding key "persons".

Please howto set routing key for the Spring Cloud Stream Rabbit producer??? To distinquish where the message will be consumed?

This is my binding configuration:

spring.config.name=streaming

spring.cloud.stream.bindings.citiesChannel.destination=streamInput
spring.cloud.stream.bindings.citiesChannel.group=cities
spring.cloud.stream.rabbit.bindings.citiesChannel.consumer.durableSubscription=true
spring.cloud.stream.rabbit.bindings.citiesChannel.consumer.bindingRoutingKey=cities

spring.cloud.stream.bindings.personsChannel.destination=streamInput
spring.cloud.stream.bindings.personsChannel.group=persons
spring.cloud.stream.rabbit.bindings.personsChannel.consumer.durableSubscription=true
spring.cloud.stream.rabbit.bindings.personsChannel.consumer.bindingRoutingKey=persons

spring.cloud.stream.bindings.producingChannel.destination=streamInput

The only way howto distinguish where the message will be send(cities or persons queue) when publishing into producingChannel is through "spring.cloud.stream.bindings.producingChannel.producer.requiredGroups" property, but this is higly unusable. Because I don't wanna know anything about the queue where my message is going to land...This is AMPQ antipattern.

I want nothing simplier then just have similar functionality like through RabbitTemplate.setRoutingKey(String routingKey) method when publishing into producingChannel...:-(

4

4 Answers

5
votes

Use routingKeyExpression on the producer side - see the documentation.

Since it's an expression, you'll need quotes: 'cities' or if the same producer sends to both, something like headers['whereToSendHeader'].

4
votes

For those of us using yaml:

spring:
  cloud:
    stream:
      rabbit:
        bindings:
          somechannel:
            producer:
              bindingRoutingKey: routingKey
              routing-key-expression: '"routingKey"'

Source

Note the bindingRoutingKey above - this is used if you expect your queue to be bound at producer startup when using spring.cloud.stream.bindings.someChannel.producer.requiredGroups

2
votes

Yes, thanks a lot.

Adding

spring.cloud.stream.rabbit.bindings.producingChannel.producer.routingKeyExpression='persons'

causes messages to land in a streaming.persons queue and

spring.cloud.stream.rabbit.bindings.producingChannel.producer.routingKeyExpression='cities'

in the streaming.cities queue. Exactly what I wanted.

Thank you. Seems that we're going to use Spring Cloud Stream in the project afterall..:-)

1
votes

Another (AMQP-agnostic) way of doing this is by using the dynamic destination support, i.e. http://docs.spring.io/autorepo/docs/spring-cloud-stream-docs/Chelsea.SR2/reference/htmlsingle/#dynamicdestination

The main difference in the case of Rabbit is that you'll end up having 2 separate exchanges ('cities' and 'persons') - so it does not leverage the routing support there, but it is portable to other messaging systems such as Kafka for example.