Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rabbitmnq: Can't declare binding with routing key #5346

Closed
oneiros-de opened this issue May 3, 2022 · 5 comments
Closed

rabbitmnq: Can't declare binding with routing key #5346

oneiros-de opened this issue May 3, 2022 · 5 comments

Comments

@oneiros-de
Copy link

I'm using org.testcontainers:rabbitmq 1.17.1 with Spring Boot 2.6.7.
I'm trying to create a test container with a binding with a routing key:

  private static final String RABBITMQ_VHOST = "mo_messaging";
  private static final String RABBITMQ_USER = "hermesmo";
  private static final String RABBITMQ_EXCHANGE = "inboundExchange";
  private static final String RABBITMQ_QUEUE = "ss7InboundQueue";
  @Container
  private static final RabbitMQContainer RABBIT_MQ_CONTAINER =
      new RabbitMQContainer(DockerImageName.parse("rabbitmq:3.7.25-management-alpine"))
          .withVhost(RABBITMQ_VHOST, true)
          .withUser(RABBITMQ_USER, "password")
          .withPermission(RABBITMQ_VHOST, RABBITMQ_USER, ".*", ".*", ".*")
          .withExchange(RABBITMQ_VHOST, RABBITMQ_EXCHANGE, ExchangeTypes.TOPIC, false, false, true,
              Collections.emptyMap())
          .withQueue(RABBITMQ_QUEUE)
          .withBinding(RABBITMQ_EXCHANGE, RABBITMQ_QUEUE, Collections.emptyMap(), "ss7", DestinationType.QUEUE.name());

This fails. The (extensive) log shows an error:

15:20:43.585 [main] ERROR 🐳 [rabbitmq:3.7.25-management-alpine] - Could not execute command [rabbitmqadmin, declare, binding, source=inboundExchange, destination=ss7InboundQueue, routing_key=ss7, destination_type=QUEUE, arguments={}]: Traceback (most recent call last):
  File "/usr/local/bin/rabbitmqadmin", line 1150, in <module>
    main()
  File "/usr/local/bin/rabbitmqadmin", line 494, in main
    method()
  File "/usr/local/bin/rabbitmqadmin", line 733, in invoke_declare
    self.post(uri, json.dumps(upload))
  File "/usr/local/bin/rabbitmqadmin", line 529, in post
    return self.http("POST", "%s/api%s" % (self.options.path_prefix, path), body)
  File "/usr/local/bin/rabbitmqadmin", line 609, in http
    raise Exception("Received response %d %s for path %s\n%s"
Exception: Received response 500 Internal Server Error for path /api/bindings/%2F/e/inboundExchange/Q/ss7InboundQueue
b''

When I use

.withBinding(RABBITMQ_EXCHANGE, RABBITMQ_QUEUE);

this fails with

15:31:19.997 [main] ERROR 🐳 [rabbitmq:3.7.25-management-alpine] - Could not execute command [rabbitmqadmin, declare, binding, source=inboundExchange, destination=ss7InboundQueue]: *** Not found: /api/bindings/%2F/e/inboundExchange/q/ss7InboundQueue

Am I doing something wrong or is this a bug?

@eddumelendez
Copy link
Member

Hi @oneiros-de
I would assume ExchangeTypes.TOPIC value is topic and DestinationType.QUEUE.name() is queue? I tried with QUEUE and got the same error, using it with lowercase the stacktrace is not displayed anymore.

I can see that you the queue and binding will not work for you because the exchange already belongs to a vhost. So, to make it work everything should be in the vhost.

As a workaround you can run rabbitmqadmin commands just like thiscontainer.execInContainer("rabbitmqadmin", "list", "queues").getStdout() in order to create a queue and binding in the same vhost where the exchange is.

@oneiros-de
Copy link
Author

I've changed the code to lowercase the constants:

.withExchange(RABBITMQ_VHOST, RABBITMQ_EXCHANGE, ExchangeTypes.TOPIC.toLowerCase(Locale.ROOT), false, false, true,
              Collections.emptyMap())
          .withQueue(RABBITMQ_QUEUE)
          .withBinding(RABBITMQ_EXCHANGE, RABBITMQ_QUEUE);

but it still fails:

10:36:28.358 [main] ERROR 🐳 [rabbitmq:3.7.7-management-alpine] - Could not execute command [rabbitmqadmin, declare, binding, source=inboundExchange, destination=ss7InboundQueue]: *** Not found: /api/bindings/%2F/e/inboundExchange/q/ss7InboundQueue

I'm following the pattern from RabbitMQContainerTest.shouldStartTheWholeEnchilada

@eddumelendez
Copy link
Member

eddumelendez commented May 4, 2022

Not sure if you read my previous comment or it was not clear enough

I can see that you the queue and binding will not work for you because the exchange already belongs to a vhost. So, to make it work everything should be in the vhost.

This is the reason why the second attempt using .withBinding(RABBITMQ_EXCHANGE, RABBITMQ_QUEUE); didn't work

RabbitMQContainerTest.shouldStartTheWholeEnchilada doesn't add vhost to the exchange as your code suggest.

.withExchange(RABBITMQ_VHOST, RABBITMQ_EXCHANGE, ExchangeTypes.TOPIC.toLowerCase(Locale.ROOT), false, false, true,
              Collections.emptyMap())

If the RABBITMQ_VHOST is removed there then it should work with the queue and the binding.

I've submitted #5348 in order to add useful methods to deal with this in the future.

@oneiros-de
Copy link
Author

If the RABBITMQ_VHOST is removed there then it should work with the queue and the binding.

Ah, thanks. Yes, I overlooked this.

I've submitted #5348 in order to add useful methods to deal with this in the future.

Thanks!

eddumelendez added a commit that referenced this issue May 11, 2022
@eddumelendez
Copy link
Member

the new methods to create exchange and binding were released with 1.17.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants