spring-bootspring-amqpspring-rabbitcloudamqp

spring-boot-starter-amqp not able to send message to AMQP exchange using user credentials with only write permission


I am trying to send message to RabbitMQ from a springboot application. Dependencies used (springboot & amqp) :

        <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>2.1.3.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
            <version>2.1.6.RELEASE</version>
        </dependency>

I can publish message to the exchange using user credentials with below access(read, write and configure):

user with configure access

but it fails when I use user without configure permission as below :

user without configure access

error received while calling rabbitTemplate.convertAndSend(exchange, null, message); :

CachingConnectionFactory       : Channel shutdown: channel error; protocol method: #method<channel.close>(reply-code=403, reply-text=ACCESS_REFUSED - access to exchange 'MyExchangeName' in vhost 'my_vHost' refused for user 'my_user', class-id=40, method-id=10

I think it is because Spring it trying to create exchange or check if exchange is present (using Admin API). If that's the case can we disable it using some property?


Solution

  • Either remove any Exchange/Queue/Binding @Beans or set the shouldDeclare property to false.

    @SpringBootApplication
    public class So62316257Application {
    
        public static void main(String[] args) {
            SpringApplication.run(So62316257Application.class, args);
        }
    
        @Bean
        public DirectExchange exchange() {
            DirectExchange exchange = new DirectExchange("foo");
            exchange.setShouldDeclare(false);
            return exchange;
        }
    
        @Bean
        public ApplicationRunner runner(RabbitTemplate template) {
            return args -> {
                template.convertAndSend("foo", "", "bar");
            };
        }
    
    }