Reputation: 17
A similar question to Send message to arbitrary vhost / exchange with RabbitMQ / Spring AMQP but I'm trying to have the AmqpAdmin
create an exchange under a specific vHost
I tried doing something like
SimpleResourceHolder.bind(((RabbitAdmin) amqpAdmin).getRabbitTemplate().getConnectionFactory(), vhost);
...
amqpAdmin.declareExchange(exchange);
...
amqpAdmin.declareQueue(queue);
amqpAdmin.declareBinding(BindingBuilder.bind(queue).to(exchange).with(routingKey));
SimpleResourceHolder.unbind(((RabbitAdmin) amqpAdmin).getRabbitTemplate().getConnectionFactory());
However AmqpAdmin
keeps using "/"
is there a way to tell it to use a specific vHost programmatically at runtime?
update 1: based on @artem-bilan I've had (partial) success by doing:
public void sendToTopic(String domain, String topic, String routingKey, Object payload) {
bindToVirtualHost(template, domain);
try {
template.setUsePublisherConnection(true);
template.convertAndSend(topic, routingKey, payload);
} finally {
unbindFromVirtualHost(template);
template.setUsePublisherConnection(false);
}
}
private void bindToVirtualHost(RabbitTemplate rabbitTemplate, String vHost) {
AbstractConnectionFactory factory = (AbstractConnectionFactory) rabbitTemplate.getConnectionFactory();
LOG.debug("binding {} to {}", factory, vHost);
factory.setVirtualHost(vHost);
}
private void unbindFromVirtualHost(RabbitTemplate rabbitTemplate) {
AbstractConnectionFactory factory = (AbstractConnectionFactory) rabbitTemplate.getConnectionFactory();
LOG.debug("unbinding {} back to default {}", factory, DEFAULT_VHOST);
factory.setVirtualHost(DEFAULT_VHOST);
}
I say (partial) because if I do:
// pre :Manually create vHost foo
sendToTopic("bar","myTopic","key","The payload"); // connection error; protocol method: #method<connection.close>(reply-code=530, reply-text=NOT_ALLOWED - vhost TNo not found, as expected
sendToTopic("foo","myTopic","key","The payload2"); // success, as expected
sendToTopic("bar","myTopic","key","The payload3"); // success, NOT EXPECTED!
and the message of payload3 goes to vHost foo
Upvotes: 1
Views: 1214
Reputation: 121292
The RabbitAdmin
cannot do more than its ConnectionFactory
allows. So, the vHost is similar to the host/port and it cannot be managed from end-user perspectiv.
See:
/**
* Create a new CachingConnectionFactory given a host name
* and port.
* @param hostNameArg the host name to connect to
* @param port the port number
*/
public CachingConnectionFactory(@Nullable String hostNameArg, int port) {
and its:
public void setVirtualHost(String virtualHost) {
The RabbitAdmin
, on its turn, is just like this:
/**
* Construct an instance using the provided {@link ConnectionFactory}.
* @param connectionFactory the connection factory - must not be null.
*/
public RabbitAdmin(ConnectionFactory connectionFactory) {
So, to deal with different vHost, you need to have its own ConnectionFactory
and RabbitAdmin
.
No, AmqpAdmin
cannot create for you a vHost. This is not an AMQP protocol operation.
See https://docs.spring.io/spring-amqp/docs/2.2.7.RELEASE/reference/html/#management-rest-api for more info.
Upvotes: 2