com.microsoft.azure.servicebus.QueueClient Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of azure-servicebus Show documentation
Show all versions of azure-servicebus Show documentation
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.
// 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 extends IMessage> messages) throws InterruptedException, ServiceBusException {
Utils.completeFuture(this.sendBatchAsync(messages));
}
@Override
public void sendBatch(Collection extends IMessage> 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 extends IMessage> messages) {
return this.sendBatchAsync(messages, TransactionContext.NULL_TXN);
}
@Override
public CompletableFuture sendBatchAsync(Collection extends IMessage> 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();
}
}