0

I referred this to receive messages from my Azure Service bus via subscription

I am able to receive the messages, but I am continuously receiving the messages until I manually terminate the program

I have a timeout option and want to receive messages only till the timeout.

It would be helpful if you can explain how the below code works and how I can modify the below code to receive messages for a particular time frame and stop receiving once my timeout has been reached.

static void registerMessageHandlerOnClient(SubscriptionClient receiveClient, ExecutorService executorService) throws Exception {
    // register the RegisterMessageHandler callback
    receiveClient.registerMessageHandler(
            new IMessageHandler() {
                // callback invoked when the message handler loop has obtained a message
                public CompletableFuture<Void> onMessageAsync(IMessage message) {
                    // receives message is passed to callback
                    if (message.getLabel() != null &&
                            message.getContentType() != null &&
                            message.getLabel().contentEquals("Scientist") &&
                            message.getContentType().contentEquals("application/json")) {

                        byte[] body = message.getBody();
                        Map scientist = GSON.fromJson(new String(body, UTF_8), Map.class);

                        System.out.printf(
                                "\n\t\t\t\t%s Message received: \n\t\t\t\t\t\tMessageId = %s, \n\t\t\t\t\t\tSequenceNumber = %s, \n\t\t\t\t\t\tEnqueuedTimeUtc = %s," +
                                        "\n\t\t\t\t\t\tExpiresAtUtc = %s, \n\t\t\t\t\t\tContentType = \"%s\",  \n\t\t\t\t\t\tContent: [ firstName = %s, name = %s ]\n",
                                receiveClient.getEntityPath(),
                                message.getMessageId(),
                                message.getSequenceNumber(),
                                message.getEnqueuedTimeUtc(),
                                message.getExpiresAtUtc(),
                                message.getContentType(),
                                scientist != null ? scientist.get("firstName") : "",
                                scientist != null ? scientist.get("name") : "");
                    }
                    return receiveClient.completeAsync(message.getLockToken());
                }

                // callback invoked when the message handler has an exception to report
                public void notifyException(Throwable throwable, ExceptionPhase exceptionPhase) {
                    System.out.printf(exceptionPhase + "-" + throwable.getMessage());
                }
            },
            // 1 concurrent call, messages are auto-completed, auto-renew duration
            new MessageHandlerOptions(1, false, Duration.ofMinutes(1)),
            executorService);
}
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
code-geek
  • 441
  • 1
  • 8
  • 22
  • Do you receive same message? – Vova Bilyachat May 20 '21 at 09:40
  • @VovaBilyachat No the messages are different and random as per our requirement – code-geek May 20 '21 at 09:49
  • I believe what you're looking for is an [`UnregisterMessageHandlerAsync`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.azure.servicebus.subscriptionclient.unregistermessagehandlerasync?view=azure-dotnet) method available in .Net SDK. It doesn't look like it is available in Java SDK. You may want to raise an issue and ask for this feature. – Gaurav Mantri May 20 '21 at 10:06
  • @GauravMantri Is there a possibility to achieve it using Java Completable Future? – code-geek May 20 '21 at 10:31
  • Honestly I have no clue, sorry! I just got curious about this functionality so I poked around a bit. You may want to ask this question on the SDK's Github repo. – Gaurav Mantri May 20 '21 at 10:40

1 Answers1

2

This cannot be done in your subscription code.

There are two options/workarounds which you can do:

  • Don't send a message to the topic continuously, have time control there.
  • Create a Timer Trigger that makes a REST API call Subscriptions - Create Or Update to make EntityStatus = ReceiveDisabled and use the similar function to make EntityStatus = Active.
Harshita Singh
  • 4,590
  • 1
  • 10
  • 13
  • Thank you very much for the answer. Option 1 is not possible in my case as I do not have control over sending message. I am an intended receiver. Could you please elaborate on Option 2 – code-geek May 20 '21 at 12:11
  • `the whole idea of Publish-subscribe does not work that way` - I disagree with that statement. It is not about publish/subscribe. The question is about reading the messages continuously however having the flexibility to open/close that channel at any time. – Gaurav Mantri May 20 '21 at 12:16
  • `Create a Timer Trigger that makes a REST API call Subscriptions - Create Or Update to make EntityStatus = ReceiveDisabled` - again the intent is not to stop messages coming into a subscription. Its about controlling how and when to read messages from a subscription. – Gaurav Mantri May 20 '21 at 12:17
  • You are right @Gaurav. But, that is not possible currently and that is why I have suggested a "workaround". You can always put your user voice here: https://feedback.azure.com/forums/34192--general-feedback – Harshita Singh May 20 '21 at 12:42
  • @code-geek, pls check out links in detail to understand the design. – Harshita Singh May 20 '21 at 15:10
  • Does this help? – Harshita Singh May 21 '21 at 07:47
  • @singhh-msft Thanks for your support. I found a recent library that supports my intended operation. – code-geek May 24 '21 at 08:28
  • Can you mark above response as an answer if it helped you? – Harshita Singh Jun 08 '21 at 06:31