All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.microsoft.azure.servicebus.QueueClient Maven / Gradle / Ivy

Go to download

Java library for Azure Service Bus. Please note, a newer package com.azure:azure-messaging-servicebus for Azure Service Bus is available as of December 2020. While this package will continue to receive critical bug fixes, we strongly encourage you to upgrade. Read the migration guide at https://aka.ms/azsdk/java/migrate/sb for more details.

There is a newer version: 3.6.7
Show newest version
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.microsoft.azure.servicebus;

import java.net.URI;
import java.sql.Date;
import java.time.Instant;
import java.util.Collection;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.microsoft.azure.servicebus.primitives.ConnectionStringBuilder;
import com.microsoft.azure.servicebus.primitives.ExceptionUtil;
import com.microsoft.azure.servicebus.primitives.MessagingEntityType;
import com.microsoft.azure.servicebus.primitives.MessagingFactory;
import com.microsoft.azure.servicebus.primitives.MiscRequestResponseOperationHandler;
import com.microsoft.azure.servicebus.primitives.ServiceBusException;
import com.microsoft.azure.servicebus.primitives.StringUtil;
import com.microsoft.azure.servicebus.primitives.Util;

public final class QueueClient extends InitializableEntity implements IQueueClient {
    private static final Logger TRACE_LOGGER = LoggerFactory.getLogger(QueueClient.class);
    private final ReceiveMode receiveMode;
    private final String queuePath;
    private final Object senderCreationLock;
    private MessagingFactory factory;
    private IMessageSender sender;
    private CompletableFuture senderCreationFuture;
    
    private MessageAndSessionPump messageAndSessionPump;
    private SessionBrowser sessionBrowser;
    private MiscRequestResponseOperationHandler miscRequestResponseHandler;

    private QueueClient(ReceiveMode receiveMode, String queuePath) {
        super(StringUtil.getShortRandomString());
        this.receiveMode = receiveMode;
        this.queuePath = queuePath;
        this.senderCreationLock = new Object();
    }
    
    public QueueClient(ConnectionStringBuilder amqpConnectionStringBuilder, ReceiveMode receiveMode) throws InterruptedException, ServiceBusException {
        this(receiveMode, amqpConnectionStringBuilder.getEntityPath());
        CompletableFuture factoryFuture = MessagingFactory.createFromConnectionStringBuilderAsync(amqpConnectionStringBuilder);
        Utils.completeFuture(factoryFuture.thenComposeAsync((f) -> this.createInternals(f, amqpConnectionStringBuilder.getEntityPath(), receiveMode), MessagingFactory.INTERNAL_THREAD_POOL));
        if (TRACE_LOGGER.isInfoEnabled()) {
            TRACE_LOGGER.info("Created queue client to connection string '{}'", amqpConnectionStringBuilder.toLoggableString());
        }
    }
    
    public QueueClient(String namespace, String queuePath, ClientSettings clientSettings, ReceiveMode receiveMode) throws InterruptedException, ServiceBusException {
        this(Util.convertNamespaceToEndPointURI(namespace), queuePath, clientSettings, receiveMode);
    }
    
    public QueueClient(URI namespaceEndpointURI, String queuePath, ClientSettings clientSettings, ReceiveMode receiveMode) throws InterruptedException, ServiceBusException {
        this(receiveMode, queuePath);
        CompletableFuture factoryFuture = MessagingFactory.createFromNamespaceEndpointURIAsyc(namespaceEndpointURI, clientSettings);
        Utils.completeFuture(factoryFuture.thenComposeAsync((f) -> this.createInternals(f, queuePath, receiveMode), MessagingFactory.INTERNAL_THREAD_POOL));
        if (TRACE_LOGGER.isInfoEnabled()) {
            TRACE_LOGGER.info("Created queue client to queue '{}/{}'", namespaceEndpointURI.toString(), queuePath);
        }
    }

    QueueClient(MessagingFactory factory, String queuePath, ReceiveMode receiveMode) throws InterruptedException, ServiceBusException {
        this(receiveMode, queuePath);
        Utils.completeFuture(this.createInternals(factory, queuePath, receiveMode));
        if (TRACE_LOGGER.isInfoEnabled()) {
            TRACE_LOGGER.info("Created queue client to queue '{}'", queuePath);
        }
    }

    private CompletableFuture createInternals(MessagingFactory factory, String queuePath, ReceiveMode receiveMode) {
        this.factory = factory;

        CompletableFuture postSessionBrowserFuture = MiscRequestResponseOperationHandler.create(factory, queuePath, MessagingEntityType.QUEUE).thenAcceptAsync((msoh) -> {
            this.miscRequestResponseHandler = msoh;
            this.sessionBrowser = new SessionBrowser(factory, queuePath, MessagingEntityType.QUEUE, msoh);
        }, MessagingFactory.INTERNAL_THREAD_POOL);

        this.messageAndSessionPump = new MessageAndSessionPump(factory, queuePath, MessagingEntityType.QUEUE, receiveMode);
        CompletableFuture messagePumpInitFuture = this.messageAndSessionPump.initializeAsync();

        return CompletableFuture.allOf(postSessionBrowserFuture, messagePumpInitFuture);
    }
    
    private CompletableFuture createSenderAsync() {
        synchronized (this.senderCreationLock) {
            if (this.senderCreationFuture == null) {
                this.senderCreationFuture = new CompletableFuture<>();
                ClientFactory.createMessageSenderFromEntityPathAsync(this.factory, this.queuePath, MessagingEntityType.QUEUE).handleAsync((sender, ex) -> {
                    if (ex == null) {
                        this.sender = sender;
                        this.senderCreationFuture.complete(null);
                    } else {
                        Throwable cause = ExceptionUtil.extractAsyncCompletionCause(ex);
                        this.senderCreationFuture.completeExceptionally(cause);
                        // Set it to null so next call will retry sender creation
                        synchronized (this.senderCreationLock) {
                            this.senderCreationFuture = null;
                        }
                    }
                    return null;
                }, MessagingFactory.INTERNAL_THREAD_POOL);
            }
            
            return this.senderCreationFuture;
        }
    }
    
    private CompletableFuture closeSenderAsync() {
        synchronized (this.senderCreationLock) {
            if (this.senderCreationFuture != null) {
                CompletableFuture senderCloseFuture = this.senderCreationFuture.thenComposeAsync((v) -> this.sender.closeAsync(), MessagingFactory.INTERNAL_THREAD_POOL);
                this.senderCreationFuture = null;
                return senderCloseFuture;
            } else {
                return CompletableFuture.completedFuture(null);
            }
        }
    }

    @Override
    public ReceiveMode getReceiveMode() {
        return this.receiveMode;
    }

    @Override
    public void send(IMessage message) throws InterruptedException, ServiceBusException {
        Utils.completeFuture(this.sendAsync(message));
    }

    @Override
    public void send(IMessage message, TransactionContext transaction) throws InterruptedException, ServiceBusException {
        Utils.completeFuture(this.sendAsync(message, transaction));
    }

    @Override
    public void sendBatch(Collection messages) throws InterruptedException, ServiceBusException {
        Utils.completeFuture(this.sendBatchAsync(messages));
    }

    @Override
    public void sendBatch(Collection messages, TransactionContext transaction) throws InterruptedException, ServiceBusException {
        Utils.completeFuture(this.sendBatchAsync(messages, transaction));
    }

    @Override
    public CompletableFuture sendAsync(IMessage message) {
        return this.createSenderAsync().thenComposeAsync((v) ->
            this.sender.sendAsync(message), MessagingFactory.INTERNAL_THREAD_POOL);
    }

    @Override
    public CompletableFuture sendAsync(IMessage message, TransactionContext transaction) {
        return this.createSenderAsync().thenComposeAsync((v) ->
            this.sender.sendAsync(message, transaction));
    }

    @Override
    public CompletableFuture sendBatchAsync(Collection messages) {
        return this.sendBatchAsync(messages, TransactionContext.NULL_TXN);
    }

    @Override
    public CompletableFuture sendBatchAsync(Collection messages, TransactionContext transaction) {
        return this.createSenderAsync().thenComposeAsync((v) ->
            this.sender.sendBatchAsync(messages, transaction), MessagingFactory.INTERNAL_THREAD_POOL);
    }

    @Override
    public CompletableFuture scheduleMessageAsync(IMessage message, Instant scheduledEnqueueTimeUtc) {
        return this.scheduleMessageAsync(message, scheduledEnqueueTimeUtc, TransactionContext.NULL_TXN);
    }

    @Override
    public CompletableFuture scheduleMessageAsync(IMessage message, Instant scheduledEnqueueTimeUtc, TransactionContext transaction) {
        return this.createSenderAsync().thenComposeAsync((v) ->
            this.sender.scheduleMessageAsync(message, scheduledEnqueueTimeUtc, transaction), MessagingFactory.INTERNAL_THREAD_POOL);
    }

    @Override
    public CompletableFuture cancelScheduledMessageAsync(long sequenceNumber) {
        return this.createSenderAsync().thenComposeAsync((v) -> this.sender.cancelScheduledMessageAsync(sequenceNumber), MessagingFactory.INTERNAL_THREAD_POOL);
    }

    @Override
    public long scheduleMessage(IMessage message, Instant scheduledEnqueueTimeUtc) throws InterruptedException, ServiceBusException {
        return Utils.completeFuture(this.scheduleMessageAsync(message, scheduledEnqueueTimeUtc));
    }

    @Override
    public long scheduleMessage(IMessage message, Instant scheduledEnqueueTimeUtc, TransactionContext transaction) throws InterruptedException, ServiceBusException {
        return Utils.completeFuture(this.scheduleMessageAsync(message, scheduledEnqueueTimeUtc, transaction));
    }

    @Override
    public void cancelScheduledMessage(long sequenceNumber) throws InterruptedException, ServiceBusException {
        Utils.completeFuture(this.cancelScheduledMessageAsync(sequenceNumber));
    }

    @Override
    public String getEntityPath() {
        return this.queuePath;
    }

    @Deprecated
    @Override
    public void registerMessageHandler(IMessageHandler handler) throws InterruptedException, ServiceBusException {
        this.messageAndSessionPump.registerMessageHandler(handler);
    }

    @Deprecated
    @Override
    public void registerMessageHandler(IMessageHandler handler, MessageHandlerOptions handlerOptions) throws InterruptedException, ServiceBusException {
        this.messageAndSessionPump.registerMessageHandler(handler, handlerOptions);
    }

    @Deprecated
    @Override
    public void registerSessionHandler(ISessionHandler handler) throws InterruptedException, ServiceBusException {
        this.messageAndSessionPump.registerSessionHandler(handler);
    }

    @Deprecated
    @Override
    public void registerSessionHandler(ISessionHandler handler, SessionHandlerOptions handlerOptions) throws InterruptedException, ServiceBusException {
        this.messageAndSessionPump.registerSessionHandler(handler, handlerOptions);
    }
    
    @Override
    public void registerMessageHandler(IMessageHandler handler, ExecutorService executorService) throws InterruptedException, ServiceBusException {
        this.messageAndSessionPump.registerMessageHandler(handler, executorService);
    }

    @Override
    public void registerMessageHandler(IMessageHandler handler, MessageHandlerOptions handlerOptions, ExecutorService executorService) throws InterruptedException, ServiceBusException {
        this.messageAndSessionPump.registerMessageHandler(handler, handlerOptions, executorService);
    }

    @Override
    public void registerSessionHandler(ISessionHandler handler, ExecutorService executorService) throws InterruptedException, ServiceBusException {
        this.messageAndSessionPump.registerSessionHandler(handler, executorService);
    }

    @Override
    public void registerSessionHandler(ISessionHandler handler, SessionHandlerOptions handlerOptions, ExecutorService executorService) throws InterruptedException, ServiceBusException {
        this.messageAndSessionPump.registerSessionHandler(handler, handlerOptions, executorService);
    }

    // No op now
    @Override
    CompletableFuture initializeAsync() {
        return CompletableFuture.completedFuture(null);
    }

    @Override
    protected CompletableFuture onClose() {
        return this.messageAndSessionPump.closeAsync().thenCompose((v) -> this.closeSenderAsync().thenCompose((u) -> this.miscRequestResponseHandler.closeAsync().thenCompose((w) -> this.factory.closeAsync())));
    }

    //    @Override
    Collection getMessageSessions() throws InterruptedException, ServiceBusException {
        return Utils.completeFuture(this.getMessageSessionsAsync());
    }

    //    @Override
    Collection getMessageSessions(Instant lastUpdatedTime) throws InterruptedException, ServiceBusException {
        return Utils.completeFuture(this.getMessageSessionsAsync(lastUpdatedTime));
    }

    //    @Override
    CompletableFuture> getMessageSessionsAsync() {
        return this.sessionBrowser.getMessageSessionsAsync();
    }

    //    @Override
    CompletableFuture> getMessageSessionsAsync(Instant lastUpdatedTime) {
        return this.sessionBrowser.getMessageSessionsAsync(Date.from(lastUpdatedTime));
    }

    @Override
    public void abandon(UUID lockToken) throws InterruptedException, ServiceBusException {
        this.messageAndSessionPump.abandon(lockToken);
    }

    @Override
    public void abandon(UUID lockToken, TransactionContext transaction) throws InterruptedException, ServiceBusException {
        this.messageAndSessionPump.abandon(lockToken, transaction);
    }

    @Override
    public void abandon(UUID lockToken, Map propertiesToModify) throws InterruptedException, ServiceBusException {
        this.messageAndSessionPump.abandon(lockToken, propertiesToModify);
    }

    @Override
    public void abandon(UUID lockToken, Map propertiesToModify, TransactionContext transaction) throws InterruptedException, ServiceBusException {
        this.messageAndSessionPump.abandon(lockToken, propertiesToModify, transaction);
    }

    @Override
    public CompletableFuture abandonAsync(UUID lockToken) {
        return this.messageAndSessionPump.abandonAsync(lockToken);
    }

    @Override
    public CompletableFuture abandonAsync(UUID lockToken, TransactionContext transaction) {
        return this.messageAndSessionPump.abandonAsync(lockToken, transaction);
    }

    @Override
    public CompletableFuture abandonAsync(UUID lockToken, Map propertiesToModify) {
        return this.messageAndSessionPump.abandonAsync(lockToken, propertiesToModify);
    }

    @Override
    public CompletableFuture abandonAsync(UUID lockToken, Map propertiesToModify, TransactionContext transaction) {
        return this.messageAndSessionPump.abandonAsync(lockToken, propertiesToModify, transaction);
    }

    @Override
    public void complete(UUID lockToken) throws InterruptedException, ServiceBusException {
        this.messageAndSessionPump.complete(lockToken);
    }

    @Override
    public void complete(UUID lockToken, TransactionContext transaction) throws InterruptedException, ServiceBusException {
        this.messageAndSessionPump.complete(lockToken, transaction);
    }

    @Override
    public CompletableFuture completeAsync(UUID lockToken) {
        return this.messageAndSessionPump.completeAsync(lockToken);
    }

    @Override
    public CompletableFuture completeAsync(UUID lockToken, TransactionContext transaction) {
        return this.messageAndSessionPump.completeAsync(lockToken, transaction);
    }

    //    @Override
    void defer(UUID lockToken) throws InterruptedException, ServiceBusException {
        this.messageAndSessionPump.defer(lockToken);
    }

    //    @Override
    void defer(UUID lockToken, Map propertiesToModify) throws InterruptedException, ServiceBusException {
        this.messageAndSessionPump.defer(lockToken, propertiesToModify);
    }

//    @Override
//    public CompletableFuture deferAsync(UUID lockToken) {
//        return this.messageAndSessionPump.deferAsync(lockToken);
//    }
//
//    @Override
//    public CompletableFuture deferAsync(UUID lockToken, Map propertiesToModify) {
//        return this.messageAndSessionPump.deferAsync(lockToken, propertiesToModify);
//    }

    @Override
    public void deadLetter(UUID lockToken) throws InterruptedException, ServiceBusException {
        this.messageAndSessionPump.deadLetter(lockToken);
    }

    @Override
    public void deadLetter(UUID lockToken, TransactionContext transaction) throws InterruptedException, ServiceBusException {
        this.messageAndSessionPump.deadLetter(lockToken, transaction);
    }

    @Override
    public void deadLetter(UUID lockToken, Map propertiesToModify) throws InterruptedException, ServiceBusException {
        this.messageAndSessionPump.deadLetter(lockToken, propertiesToModify);
    }

    @Override
    public void deadLetter(UUID lockToken, Map propertiesToModify, TransactionContext transaction) throws InterruptedException, ServiceBusException {
        this.messageAndSessionPump.deadLetter(lockToken, propertiesToModify, transaction);
    }

    @Override
    public void deadLetter(UUID lockToken, String deadLetterReason, String deadLetterErrorDescription) throws InterruptedException, ServiceBusException {
        this.messageAndSessionPump.deadLetter(lockToken, deadLetterReason, deadLetterErrorDescription);
    }

    @Override
    public void deadLetter(UUID lockToken, String deadLetterReason, String deadLetterErrorDescription, TransactionContext transaction) throws InterruptedException, ServiceBusException {
        this.messageAndSessionPump.deadLetter(lockToken, deadLetterReason, deadLetterErrorDescription, transaction);
    }

    @Override
    public void deadLetter(UUID lockToken, String deadLetterReason, String deadLetterErrorDescription, Map propertiesToModify) throws InterruptedException, ServiceBusException {
        this.messageAndSessionPump.deadLetter(lockToken, deadLetterReason, deadLetterErrorDescription, propertiesToModify);
    }

    @Override
    public void deadLetter(UUID lockToken, String deadLetterReason, String deadLetterErrorDescription, Map propertiesToModify, TransactionContext transaction) throws InterruptedException, ServiceBusException {
        this.messageAndSessionPump.deadLetter(lockToken, deadLetterReason, deadLetterErrorDescription, propertiesToModify, transaction);
    }

    @Override
    public CompletableFuture deadLetterAsync(UUID lockToken) {
        return this.messageAndSessionPump.deadLetterAsync(lockToken);
    }

    @Override
    public CompletableFuture deadLetterAsync(UUID lockToken, TransactionContext transaction) {
        return this.messageAndSessionPump.deadLetterAsync(lockToken, transaction);
    }

    @Override
    public CompletableFuture deadLetterAsync(UUID lockToken, Map propertiesToModify) {
        return this.messageAndSessionPump.deadLetterAsync(lockToken, propertiesToModify);
    }

    @Override
    public CompletableFuture deadLetterAsync(UUID lockToken, Map propertiesToModify, TransactionContext transaction) {
        return this.messageAndSessionPump.deadLetterAsync(lockToken, propertiesToModify, transaction);
    }

    @Override
    public CompletableFuture deadLetterAsync(UUID lockToken, String deadLetterReason, String deadLetterErrorDescription) {
        return this.messageAndSessionPump.deadLetterAsync(lockToken, deadLetterReason, deadLetterErrorDescription);
    }

    @Override
    public CompletableFuture deadLetterAsync(UUID lockToken, String deadLetterReason, String deadLetterErrorDescription, TransactionContext transaction) {
        return this.messageAndSessionPump.deadLetterAsync(lockToken, deadLetterReason, deadLetterErrorDescription, transaction);
    }

    @Override
    public CompletableFuture deadLetterAsync(UUID lockToken, String deadLetterReason, String deadLetterErrorDescription, Map propertiesToModify) {
        return this.messageAndSessionPump.deadLetterAsync(lockToken, deadLetterReason, deadLetterErrorDescription, propertiesToModify);
    }

    @Override
    public CompletableFuture deadLetterAsync(UUID lockToken, String deadLetterReason, String deadLetterErrorDescription, Map propertiesToModify, TransactionContext transaction) {
        return this.messageAndSessionPump.deadLetterAsync(lockToken, deadLetterReason, deadLetterErrorDescription, propertiesToModify, transaction);
    }

    @Override
    public int getPrefetchCount() {
        return this.messageAndSessionPump.getPrefetchCount();
    }

    @Override
    public void setPrefetchCount(int prefetchCount) throws ServiceBusException {
        this.messageAndSessionPump.setPrefetchCount(prefetchCount);
    }

    @Override
    public String getQueueName() {
        return this.getEntityPath();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy