3

I have the following implementation to consume the message from Azure Service Bus using Spring Boot application however I want to be able to control the ServiceBusConsumer from automatically start listening to the Topic using Spring boot profile property

something like this in the application.yaml

 servicebus.consumer.enable=false

it should disable the ServiceBusConsumer from listening to the Topic(s) as well as I should be able to start the ServiceBusConsumer using a REST API - eg: ./api/servicebus/consumer/start?

import com.microsoft.azure.servicebus.ExceptionPhase;
import com.microsoft.azure.servicebus.IMessage;
import com.microsoft.azure.servicebus.IMessageHandler;
import com.microsoft.azure.servicebus.ISubscriptionClient;
import lombok.extern.log4j.Log4j2;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import java.util.concurrent.CompletableFuture;

@Log4j2
@Component
class ServiceBusConsumer implements Ordered {

    private final ISubscriptionClient iSubscriptionClient;

    ServiceBusConsumer(ISubscriptionClient isc) {
        this.iSubscriptionClient = isc;
    }

    @EventListener(ApplicationReadyEvent.class)
    public void consume() throws Exception {

        this.iSubscriptionClient.registerMessageHandler(new IMessageHandler() {

            @Override
            public CompletableFuture<Void> onMessageAsync(IMessage message) {
                log.info("received message " + new String(message.getBody()) + " with body ID " + message.getMessageId());
                return CompletableFuture.completedFuture(null);
            }

            @Override
            public void notifyException(Throwable exception, ExceptionPhase phase) {
                log.error("eeks!", exception);
            }
        });

    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }
}
One Developer
  • 99
  • 5
  • 43
  • 103

2 Answers2

2

You can create the ServiceBusConsumer bean conditionally by adding the @ConditionalOnProperty annotation like so, to make sure the bean is created only when servicebus.consumer.enabled=true:

@Log4j2
@Component
@ConditionalOnProperty(prefix = "servicebus.consumer", name = "enabled") 
class ServiceBusConsumer implements Ordered {
...
}
Domenico Sibilio
  • 1,189
  • 1
  • 7
  • 20
  • 1
    Thank you, I should also able to start the ServiceBusConsumer using a REST API - eg: ./api/servicebus/consumer/start? Can you guide me on how to achieve this? – One Developer Feb 12 '21 at 14:31
  • 1
    You could inject to ISubscriptionClient for it to be available to the REST controller, and register the message handler there, once someone invokes the REST API. If you'd like to stop an active ISubscriptionClient you can check out the close/closeAsync methods of the ISubscriptionClient. Otherwise you could also check the ServiceBusTopicTemplate subscribe/unsubscribe methods or Spring Cloud Stream Binder Service Bus that also includes the start and stop bindings feature: org.springframework.cloud.stream.binder.Binding start/stop – Domenico Sibilio Feb 12 '21 at 15:01
  • @DomenicoSibilio https://stackoverflow.com/questions/75280748/control-azure-service-bus-consumer-to-start-or-stop-listening-from-the-topic-in Can you give answer to this question ? It is similar to this question. – Kush Patel Jan 30 '23 at 07:01
1

The official documents specify you could use the spring.cloud.azure.servicebus.enabled property to disable the consumer entirely.

Reference: https://microsoft.github.io/spring-cloud-azure/4.2.0/reference/html/index.html#servicebus-connection-configuration

Daniel Pop
  • 456
  • 1
  • 6
  • 23