Search code examples
amqpspring-amqp

Is ThreadChannelConnectionFactory supposed to be compatible with RabbitAdmin automatic declaration?


As illustrated in the (failing) test below, Declarables are not declared when a connection is created:

private const val QUEUE = "test"

@SpringBootTest
class ThreadChannelConnectionFactoryTest {

    @Autowired
    private lateinit var admin: AmqpAdmin

    @Test
    fun queueExists() {
        assertThat(admin.getQueueInfo(QUEUE)).isNotNull
    }

    @SpringBootApplication(proxyBeanMethods = false)
    protected class TestApplication {

        @Bean
        fun queue() = QueueBuilder.nonDurable(QUEUE).build()

        @Bean
        fun connectionFactory() = ThreadChannelConnectionFactory(RabbitConnectionFactoryBean().rabbitConnectionFactory)
    }
}

Commenting out the connectionFactory bean definition makes the test pass, since Spring Boot then creates an old-fashioned CachingConnectionFactory.

Is there any good reason for that or has it simply been overlooked? What are my options if I need both feature sets?

  • ThreadLocal channels
  • automatic Declarable declaration

EDIT : The following workaround seems to work as of 2.3.1:

class ConnectionListenerFiringThreadChannelConnectionFactory(connectionFactory: ConnectionFactory, isPublisher: Boolean) : ThreadChannelConnectionFactory(connectionFactory) {

    init {
        if (!isPublisher) {
            setPublisherConnectionFactory(ConnectionListenerFiringThreadChannelConnectionFactory(connectionFactory, true))
        }
    }

    constructor(connectionFactory: ConnectionFactory) : this(connectionFactory, false)

    override fun createConnection(): Connection {
        val connection = super.createConnection()
        connectionListener.onCreate(connection)

        return connection
    }
}

Solution

  • It's a bug; your work around is correct.

    https://github.com/spring-projects/spring-amqp/issues/1268