0

I'm using RabbitMQ. I've defined a queue with priority, and I can send messages to this queue with some priority value using RMQ GUI, and consumers also get the messages in sorted order, but when I try to send the message from my java code using Stream bridge, I don't know how to specify the priority with the message. Here's what I have tried :

  1. I have added x-max-priority: 10 to the queue while creating the queue.

  2. Consumer example =

     @Bean
     public Consumer<Message<String>> testListener() {
     return (m) -> {
         System.out.println("inside consumer with message : " + m);
         System.out.println("headers : " + m.getHeaders());
         System.out.println("payload : " + m.getPayload());
     };
     }
    
  3. Producer example =

     @GET
     @Path("test/")
     public void test(@Context HttpServletRequest request) {
     System.out.println("inside test");
     try {
         String payload = "hello world";
         logger.info("going to send a message : {}", payload);
         int priority = 5;
         Message<String> message = MessageBuilder.withPayload(payload)
                         .setHeader("priority", priority)
                         .build();
         boolean res = STREAM_BRIDGE.send("testWriter-out-0", message);
         System.out.println(message);
         System.out.println(res);
     } catch (Exception e) {
         logger.error(e);
     }
    }
    

The output of the Producer =

    -> inside test
    -> GenericMessage [payload=hello world, headers={priority=5, id=some_id, timestamp=epoch}]
    -> true

The output of the Consumer =

    -> inside consumer with message : GenericMessage [payload=hello world, headers={amqp_receivedDeliveryMode=PERSISTENT, amqp_receivedExchange=test_exchange, amqp_deliveryTag=1, deliveryAttempt=1, amqp_consumerQueue=test_exchange.ats, amqp_redelivered=false, amqp_receivedRoutingKey=test_exchange, amqp_timestamp=date_time, amqp_messageId=some_id, id=some_id, amqp_consumerTag=some_tag, sourceData=(Body:'hello world' MessageProperties [headers={}, timestamp=date_time, messageId=some_id, contentType=application/json, contentLength=0, receivedDeliveryMode=PERSISTENT, priority=0, redelivered=false, receivedExchange=test_exchange, receivedRoutingKey=test_exchange, deliveryTag=1, consumerTag=some_tag, consumerQueue=test_exchange.ats]), contentType=application/json, timestamp=epoch}]
    -> headers : {amqp_receivedDeliveryMode=PERSISTENT, amqp_receivedExchange=test_exchange, amqp_deliveryTag=1, deliveryAttempt=1, amqp_consumerQueue=test_exchange.ats, amqp_redelivered=false, amqp_receivedRoutingKey=test_exchange, amqp_timestamp=date_time, amqp_messageId=some_id, id=some_id, amqp_consumerTag=tag, sourceData=(Body:'hello world' MessageProperties [headers={}, timestamp=date_time, messageId=some_id, contentType=application/json, contentLength=0, receivedDeliveryMode=PERSISTENT, priority=0, redelivered=false, receivedExchange=test_exchange, receivedRoutingKey=test_exchange, deliveryTag=1, consumerTag=tag, consumerQueue=test_exchange.ats]), contentType=application/json, timestamp=epoch}
    -> payload : hello world
    

So the message goes to RMQ and the consumer also gets the message, but on RMQ GUI when I perform Get-message operation on the Queue, I get this result =>

    Message 1
    The server reported 0 messages remaining.
    Exchange    test_exchange
    Routing Key test_exchange
    Redelivered ○
    Properties  
                timestamp:  timestamp
                message_id: some_id
                priority:   0
                delivery_mode:  2
                headers:    
                content_type:   application/json

    Payload     hello world
    11 bytes
    Encoding: string
    

As we can see in the above result, priority is set to 0 by RMQ (and hence in the Consumer, I get the messages in the FIFO manner, not in a priority-based manner) and inside headers : only one header is present "content_type: application/json", so I think the priority is not a part of the header but is a part of properties, then how to set message properties using StreamBridge?

To conclude, I am trying to figure out how to set the priority of a message dynamically while sending it using StreamBridge, any help would be appreciated, thanks in advance !

amey
  • 28
  • 7
  • 1
    Works well for me. I see both property and header entries for the `priority` in RabbitMQ GUI. Any chances you can share with us a simple project to reproduce and play with? To determine what is the difference between our configurations. BTW I don't specify any `headerPatterns` to override default for mapping all. – Artem Bilan Jun 09 '22 at 16:36
  • 1
    hi, Artem thanks for the reply, I did not understand the last part of your comment, one with the "headerPatterns" (I am new to RabbitMQ terminology), also its quite difficult to give you the project, but I can provide some info like version etc things, I'm currently using the following versions of the given services, RabbitMQ = 3.9.13, Java = 1.8, springboot version = 2.3.3.RELEASE, spring-cloud-starter-stream-rabbit = 3.0.3.RELEASE, spring-cloud-starter-config = 2.2.0.RELEASE – amey Jun 09 '22 at 17:36
  • 1
    Also while checking the internet found this thread, does this issue seems related to my situation? => https://github.com/spring-cloud/spring-cloud-stream/issues/1931 – amey Jun 09 '22 at 17:38
  • 1
    Oh! It definitely looks like. You see that issue has been fixed in version `3.1.0`, but you still use an old one `3.0.3`. I wonder what drove you to not use the latest one: https://spring.io/projects/spring-cloud-stream#learn ?.. – Artem Bilan Jun 09 '22 at 17:47
  • Facing some problems with the dependency management (with old project structure) that's why kept the version to a minimum (on which basic required things are working) but now will try to update it to the next version (which has solved this issue), so basically, to solve my problem I need to update my spring-cloud-starter-stream-rabbit from version 3.0.3.RELEASE to 3.1.0 version right? – amey Jun 09 '22 at 17:57
  • but other than this version problem, this way of setting priority is the correct way, right? passing `priority = [some_Integer]` in the header, as shown in the code snippet `Message message = MessageBuilder.withPayload(payload) .setHeader("priority", priority) .build(); boolean res = STREAM_BRIDGE.send("testWriter-out-0", message);` – amey Jun 09 '22 at 17:59
  • 1
    It is. I definitely use the same code in my test. – Artem Bilan Jun 09 '22 at 18:13
  • 1
    Why not `3.2.4` already? Technically you need just the latest Spring Boot and latest Spring Cloud. The rest should be pulled automatically as transitive deps. – Artem Bilan Jun 09 '22 at 18:15
  • 1
    ok, thanks, will try to upgrade it to the latest, and to conclude I'll first try upgrading the version of `spring-cloud-starter-stream-rabbit to 3.1.3` and it will internally upgrade the version of `spring-cloud-stream to 3.1.3` to solve the issue, and as per your suggestion will try to upgrade it further to the latest version `(3.2.4)` as well. – amey Jun 09 '22 at 18:27

1 Answers1

1

Please, consider to use the latest Spring Cloud Stream: https://spring.io/projects/spring-cloud-stream#learn.

Apparently your spring-cloud-starter-stream-rabbit = 3.0.3.RELEASE is old enough to suffer from the issue https://github.com/spring-cloud/spring-cloud-stream/issues/1931.

Have just tested with the latest one and I got the proper priority property on the message posted into RabbitMQ queue by the mentioned StreamBridge.

Artem Bilan
  • 113,505
  • 11
  • 91
  • 118