Hello people,

I am using "camel-rabbit" instead of "rabbit-amqp" for different reasons. By using "camel-rabbit" I loose all the autoconfiguration of

  • MetricRegistry
  • and HealthIndicator

To make this work, I craeted my own implementations for the features in question:

/**
 * By using camel-rabbit instead of spring-amqp you loose the auto configuration feature of AMQP Rabbit health info.
 * Therefore, we do the health check ourselves.
 *
 * @see: {@link org.springframework.boot.actuate.amqp.RabbitHealthIndicator}
 */
@Component
public class RabbitHealthIndicator extends AbstractHealthIndicator {

  private ConnectionFactory connectionFactory;

  public RabbitHealthIndicator(ConnectionFactory connectionFactory) {
    this.connectionFactory = connectionFactory;
  }

  @Override
  protected void doHealthCheck(Health.Builder builder) throws Exception {
    builder.up().withDetail("version", getVersion());
  }

  private String getVersion() throws IOException, TimeoutException {
    try( Connection connection = connectionFactory.newConnection() ) {
      Map<String, Object> properties = connection.getServerProperties();
      return properties.get("version").toString();
    }
  }
}
/**
 * By using camel-rabbit instead of spring-amqp you loose the auto configuration feature of AMQP Rabbit metrics.
 * Therefore, we do the wiring for {@link ConnectionFactory} and {@link RabbitMetrics} manually
 *
 * @see: {@link org.springframework.boot.actuate.autoconfigure.metrics.amqp.RabbitConnectionFactoryMetricsPostProcessor}
 * @see  {@link org.springframework.boot.actuate.autoconfigure.metrics.amqp.RabbitMetricsAutoConfiguration}
 */
@Configuration
// TODO: why does this break the metrics configuration ?
//@ConditionalOnBean({ ConnectionFactory.class, MeterRegistry.class })
public class RabbitMetricsAutoConfiguration {

  @Autowired
  private ConnectionFactory connectionFactory;
  @Autowired
  private MeterRegistry registry;

  @PostConstruct
  public void postConstruct() {
    new RabbitMetrics(connectionFactory, Tags.of("name", RabbitMqConfig.CONNECTION_FACTORY_NAME)).bindTo(registry);
  }
}

In my experience, either using "camel-rabbit" or "spring-amqp" both rely on the "ConnectionFactory" from the "rabbit-client". In my project, the camel-rabbit components are configured to reuse the "ConnectionFactory" available in the Spring Context.

It would be great to have the default implementation of "RabbitMetricsAutoConfiguration" and "RabbitHealthIndicator" only dependend on "ConnectionFactory".

Best regards

Comment From: snicoll

@rfelgent I've edited your comment to improve the formatting. You might want to check out this Mastering Markdown guide for future reference.

Comment From: wilkinsona

As things stand, we don't create a com.rabbitmq.client.ConnectionFactory bean so switching RabbitMetricsAutoConfiguration and RabbitHealthIndicator to use one isn't a completely straightforward change to make. That said, it does seem like a reasonable thing to try to do. Our DataSource health indicator doesn't require a JdbcTemplate bean so it seems a little inconsistent for our Rabbit health indicator to rely on RabbitTemplate.

Comment From: rfelgent

Hello people,

thx for you replies.

@snicoll , thx for your edits and sorry, that my formatting was not properly! @wilkinsona . I did not think about JdbcTemplate, but your hint about the inconsistency is correct. In my opinion, this is another (good) argument for my wish to not depend on spring-amqp ...

What exactly do you mean by saying:

we don't create a com.rabbitmq.client.ConnectionFactory

Imho, you do create (or reference) the ConnectionFactory within the post processor RabbitConnectionFactoryMetricsPostProcessor. Unfortunately, this factory is from spring-amqp.

Maybe it is an idea to move the functionality of "AbstractConnectionFactory" class to spring-boot-autoconfigure and the implementation supports only the "raw" rabbit connection factory.

Comment From: wilkinsona

What exactly do you mean by saying:

we don't create a com.rabbitmq.client.ConnectionFactory

You missed the word "bean" off the end that is important. While we do create a ConnectionFactory it is not created as a bean and, therefore, is not available for dependency injection. This means that we can't inject it into RabbitHealthIndicator and RabbitMetricsAutoConfiguration without defining an extra bean and making some public API changes.

Maybe it is an idea to move the functionality of "AbstractConnectionFactory" class to spring-boot-autoconfigure

AbstractConnectionFactory is part of the Spring AMQP project. We can't move it into Spring Boot as it would create a circular dependency between the two projects.

Comment From: rfelgent

Hi @wilkinsona ,

AbstractConnectionFactory is part of the Spring AMQP project. We can't move it into Spring Boot as it would create a circular dependency between the two projects.

Sorry, I did not express myself very good. I know about the circular dependency. I was talking about the functionality in general (facade, abstraction over connectionfactory).

Anyway, the AbstractConnectionFactory is available as Spring managed bean, right ? If so, in my opinion it should not be a big deal to work with either bean ConnectionFactory or bean AbstractConnectionFactory.

Comment From: wilkinsona

We’re cleaning out the issue tracker and closing issues that we’ve not seen much demand to fix. Feel free to comment with additional justifications if you feel that this one should not have been closed.