com.microsoft.azure.servicebus.SubscriptionClient 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. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
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 java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.microsoft.azure.servicebus.primitives.ConnectionStringBuilder;
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;
import com.microsoft.azure.servicebus.rules.Filter;
import com.microsoft.azure.servicebus.rules.RuleDescription;
public final class SubscriptionClient extends InitializableEntity implements ISubscriptionClient
{
private static final Logger TRACE_LOGGER = LoggerFactory.getLogger(SubscriptionClient.class);
private static final String SUBSCRIPTIONS_DELIMITER = "/subscriptions/";
private final ReceiveMode receiveMode;
private final String subscriptionPath;
private MessagingFactory factory;
private MessageAndSessionPump messageAndSessionPump;
private SessionBrowser sessionBrowser;
private MiscRequestResponseOperationHandler miscRequestResponseHandler;
public static final String DEFAULT_RULE_NAME = "$Default";
private SubscriptionClient(ReceiveMode receiveMode, String subscriptionPath)
{
super(StringUtil.getShortRandomString());
this.receiveMode = receiveMode;
this.subscriptionPath = subscriptionPath;
}
public SubscriptionClient(ConnectionStringBuilder amqpConnectionStringBuilder, ReceiveMode receiveMode) throws InterruptedException, ServiceBusException
{
this(receiveMode, amqpConnectionStringBuilder.getEntityPath());
CompletableFuture factoryFuture = MessagingFactory.createFromConnectionStringBuilderAsync(amqpConnectionStringBuilder);
Utils.completeFuture(factoryFuture.thenComposeAsync((f) -> this.createPumpAndBrowserAsync(f), MessagingFactory.INTERNAL_THREAD_POOL));
if(TRACE_LOGGER.isInfoEnabled())
{
TRACE_LOGGER.info("Created subscription client to connection string '{}'", amqpConnectionStringBuilder.toLoggableString());
}
}
public SubscriptionClient(String namespace, String subscriptionPath, ClientSettings clientSettings, ReceiveMode receiveMode) throws InterruptedException, ServiceBusException
{
this(Util.convertNamespaceToEndPointURI(namespace), subscriptionPath, clientSettings, receiveMode);
}
public SubscriptionClient(URI namespaceEndpointURI, String subscriptionPath, ClientSettings clientSettings, ReceiveMode receiveMode) throws InterruptedException, ServiceBusException
{
this(receiveMode, subscriptionPath);
CompletableFuture factoryFuture = MessagingFactory.createFromNamespaceEndpointURIAsyc(namespaceEndpointURI, clientSettings);
Utils.completeFuture(factoryFuture.thenComposeAsync((f) -> this.createPumpAndBrowserAsync(f), MessagingFactory.INTERNAL_THREAD_POOL));
if (TRACE_LOGGER.isInfoEnabled()) {
TRACE_LOGGER.info("Created subscription client to subscription '{}/{}'", namespaceEndpointURI.toString(), subscriptionPath);
}
}
SubscriptionClient(MessagingFactory factory, String subscriptionPath, ReceiveMode receiveMode) throws InterruptedException, ServiceBusException
{
this(receiveMode, subscriptionPath);
Utils.completeFuture(this.createPumpAndBrowserAsync(factory));
TRACE_LOGGER.info("Created subscription client to subscripton '{}'", subscriptionPath);
}
private CompletableFuture createPumpAndBrowserAsync(MessagingFactory factory)
{
this.factory = factory;
CompletableFuture postSessionBrowserFuture = MiscRequestResponseOperationHandler.create(factory, this.subscriptionPath, MessagingEntityType.SUBSCRIPTION).thenAcceptAsync((msoh) -> {
this.miscRequestResponseHandler = msoh;
this.sessionBrowser = new SessionBrowser(factory, this.subscriptionPath, MessagingEntityType.SUBSCRIPTION, msoh);
}, MessagingFactory.INTERNAL_THREAD_POOL);
this.messageAndSessionPump = new MessageAndSessionPump(factory, this.subscriptionPath, MessagingEntityType.SUBSCRIPTION, receiveMode);
CompletableFuture messagePumpInitFuture = this.messageAndSessionPump.initializeAsync();
return CompletableFuture.allOf(postSessionBrowserFuture, messagePumpInitFuture);
}
@Override
public ReceiveMode getReceiveMode() {
return this.receiveMode;
}
@Override
public String getEntityPath() {
return this.subscriptionPath;
}
@Override
public void addRule(RuleDescription ruleDescription) throws InterruptedException, ServiceBusException {
Utils.completeFuture(this.addRuleAsync(ruleDescription));
}
@Override
public CompletableFuture addRuleAsync(RuleDescription ruleDescription) {
return this.miscRequestResponseHandler.addRuleAsync(ruleDescription);
}
@Override
public void addRule(String ruleName, Filter filter) throws InterruptedException, ServiceBusException {
Utils.completeFuture(this.addRuleAsync(ruleName, filter));
}
@Override
public CompletableFuture addRuleAsync(String ruleName, Filter filter) {
return this.addRuleAsync(new RuleDescription(ruleName, filter));
}
@Override
public void removeRule(String ruleName) throws InterruptedException, ServiceBusException {
Utils.completeFuture(this.removeRuleAsync(ruleName));
}
@Override
public CompletableFuture removeRuleAsync(String ruleName) {
return this.miscRequestResponseHandler.removeRuleAsync(ruleName);
}
@Override
public Collection getRules() throws ServiceBusException, InterruptedException {
return Utils.completeFuture(this.getRulesAsync());
}
@Override
public CompletableFuture> getRulesAsync()
{
// Skip and Top can be used to implement pagination.
// In this case, we are trying to fetch all the rules associated with the subscription.
int skip = 0, top = Integer.MAX_VALUE;
return this.miscRequestResponseHandler.getRulesAsync(skip, top);
}
@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.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 getTopicName() {
String entityPath = this.getEntityPath();
String[] parts = Pattern.compile(SUBSCRIPTIONS_DELIMITER, Pattern.CASE_INSENSITIVE).split(entityPath, 2);
return parts[0];
}
@Override
public String getSubscriptionName() {
String entityPath = this.getEntityPath();
String[] parts = Pattern.compile(SUBSCRIPTIONS_DELIMITER, Pattern.CASE_INSENSITIVE).split(entityPath, 2);
if(parts.length == 2)
{
return parts[1];
}
else
{
throw new RuntimeException("Invalid entity path in the subscription client.");
}
}
}